FAQ Python
![logo](./images/FAQPython.png)
FAQ PythonConsultez toutes les FAQ
Nombre d'auteurs : 11, nombre de questions : 188, dernière mise à jour : 14 juin 2021
![Ouvrir](/template/kit/kitmoins.png)
Vous 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