FAQ Python

FAQ PythonConsultez toutes les FAQ
Nombre d'auteurs : 11, nombre de questions : 188, dernière mise à jour : 14 juin 2021
Sommaire→Programmation objetVous pouvez sauvegarder de manière très simples dans des fichiers des objets python basiques ou même des objets
que vous auriez vous-mêmes définis.
S'il s'agit de nombres (int, float, ...), chaînes de caractères, conteneurs (tuples, listes, dictionnaires) contenant uniquement
des objets de types élémentaires, vous pouvez utiliser le module marshal. Sinon, s'il s'agit d'instances de classe
que vous avez vous-mêmes définis, utilisez le module pickle ou
cPickle (qui est beaucoup plus rapide que pickle)
La fonction dump(value, file) où value est l'objet élémentaire à sauvegarder et file
est un fichier ouvert en écriture.
La focntion load(fileobj) permet de lire un fichier et retourne l'objet enregistré; fileobj étant un fichier
ouvert en lecture.
import marshal
import cPickle
dico = {}
dico['toto'] = [23,'53453',{'a':5}]
marshal.dump(dico, open("mondico", 'wb')) ## Sauvegarde du dictionnaire
print marshal.load(open("mondico", "rb")) ## Rechargement du dictionnaire
class toto:
def __init__(self):
self.x = 5
tutu = toto()
cPickle.dump(tutu, open("toto2", "wb")) ## Sauvegarde de l'objet tutu
print cPickle.load(open("toto2")).x ## Rechargement de l'objet tutu
Vous pouvez avoir besoin de travailler sur des objets contenant directement le contenu d'images ou bien de transférer des objets devant travailler
sur des images. Vous devez tout d'abord récupérer et installer la bibliothèque Pil.
Au lieu de devoir ainsi fournir un fichier contenant l'objet et chacune des images dans des fichier séparés ou dans un fichier .zip, vous
pouvez alors décider d'utiliser un unique fichier qui peut ainsi faciliter la procédure. En revanche, si vous travaillez avec des images
compressées, le fichier que nous allons créer sera beaucoup plus gros que l'ensemble des fichiers images le constituant.
Pour cela, il suffit tout d'abord d'ouvrir chaque image en tant fichier binaire grâce à la commande open et le paramètre 'rb' et
de les conserver dans une variable ou un autre conteneur (comme une liste ou un dictionnaire).
la méthode seek(0) vous permet de vous placer au début du fichier et la méthode read() de lire le contenu entier du fichier ouvert.
import cPickle
img1 = open('first.jpg', 'rb')
img1.seek(0)
w1 = img1.read()
img1.close()
img2 = open('second.jpg', 'rb')
img2.seek(0)
w2 = img2.read()
img2.close()
dic = {'img1' : w1, 'img2': w2}
cPickle.dump(dic, open("monfichier", "wb"))Une fois que vous avez récupérer le fichier créé avec cPickle, vous pouvez récupérer en connaissant la structure du fichier les 2 images transmises. Pour cela, on va utiliser le module cStringIO qui permet de lire et de créer des fichiers en mémoire. Par la méthode write, nous allons écrire le contenu de nos variables, se repositionner avec seek(0) au début du fichier. Enfin, nous allon récréer une image grâce à Pil et la fonction Image.open.
import Image, cPickle, cStringIO
monobjet = cPickle.load(open("monfichier"))
img1 = cStringIO.StringIO()
img1.write(monobjet['img1'])
img1.seek(0)
im1 = Image.open(img1)
im1.save('first.jpg')
img2 = cStringIO.StringIO()
img2.write(monobjet['img2'])
img2.seek(0)
im2 = Image.open(img2)
im2.save('second.jpg')Vous pouvez récupérer le nom de la classe d'un objet en appliquant à cet objet l'attribut .__class__.__name__
>>> a = 5
>>> a.__class__.__name__
'int'
>>> class toto: pass
>>> b = toto()
>>> b.__class__.__name__
'toto'Les objets immuables que l'on utilise traditionnellement sont les nombres et les chaînes de caractères. Pour ces objets, on ne peut effectuer un héritage traditionnelle qui utilise la méthode __init__ qui n'a aucune influence sur la valeur retournée par le constructeur dans ce cas-là. Vous devez alors utiliser la méthode __new__(...) comme sur l'exemple suivant. Si vous redéfinissez ensuite des fonctions que la classe parente possède déjà, n'oubliez pas d'utiliser si nécessaire la fonction super(cls, obj) qui permet d'appeler les fonctions de la classe mère sous peine parfois d'obtenir des erreurs de récursion infinie. Etudiez ainsi l'exemple suivant où la classe angle dérive de la classe int en redéfinissant quelques fonctions basiques.
class angle(int):
def __new__(self, n):
## On retourne l'angle principale dans l'intervalle [0;360]
return int.__new__(self, n % 360)
def __sub__(self, n):
## On calcule la différence de 2 angles en retournant l'angle principal
return angle(super(angle, self).__sub__(n))
def __add__(self, n):
## On calcule la somme de 2 angles en retournant l'angle principal
return angle(super(angle, self).__add__(n))
A = angle(540)
B = angle(- 460)
print A, B, type(A), type(B) ## 180 260 <class '__main__.angle'> <class '__main__.angle'>
print A - B, type(A - B) ## 280 <class '__main__.angle'>
print A + B, type(A - B) ## 80 <class '__main__.angle'>En Python, on peut surcharger tous les opérateurs. L'ensemble de ces opérateurs est identique à ceux que l'on retrouve
dans le module operator. Ces
opérateurs se redéfinissent donc dans une classe de la manière suivante def __operateur__(self, ...): ...
Dans l'exemple suivant, nous allons créer une classe Vecteur et définir les opérations habituelles sur un vecteur
# -*- coding: cp1252 -*-
import math
class Vector:
def __init__(self, x=0, y=0):
self.x=x
self.y=y
def __eq__(self, vB): return (self.x==vB.x) and (self.y==vB.y) ## test l'égalité de 2 vecteurs
def __add__(self, vB): return Vector(self.x+vB.x,self.y+vB.y) ## retourne le vecteur somme
def __sub__(self, vB): return Vector(self.x-vB.x,self.y-vB.y) ## retourne le vecteur différence
def __mul__(self, c):
if isinstance(c,Vector): return self.x*c.x+self.y*c.y ## retourne le produit scalaire
else: return Vector(c*self.x,c*self.y) ## retourne le vecteur multiplé par un scalaire
def __div__(self, c): return Vector(self.x/c, self.y/c) ## retourne le vecteur ayant subi une division scalaire
def __abs__(self): return math.hypot(self.x, self.y) ## retourne la norme2 du vecteur
def __str__(self): return '('+str(self.x)+','+str(self.y)+')' ## retourne la réprésentation du vecteur sous forme d'une chaîne
>>> a = Vector(4,5)
>>> b = Vector(6,7)
>>> print a==b
False
>>> print a+b
(10,12)
>>> print a-b
(-2,-2)
>>> print a*b
59
>>> print abs(a)
6.40312423743


