Le module pickle implémente un algorithme basique mais puissant
pour ``pickler'' (ou serialiser, marshaller ou aplatir) à peu près tous
les types d'objets. C'est l'opération qui consiste à convertir des
objets en un flux d'octets (et réciproquement : ``dépickler''). C'est
une notion plus primitive que la persistance - bien que
pickle lise et écrive des objets fichiers, il ne gère pas
le problème de nommer les objets persistants, ni le domaine (encore
plus compliqué) des accès concurrents aux objets persistants.
Le module pickle peut transformer un objet complexe en un
flux d'octets et il peut transformer le flux d'objet en un objet
ayant la même structure interne. La chose la plus évidente à faire
avec ces flux d'octets est de les écrire dans un fichier, mais il est
aussi concevable de les envoyer sur un réseau ou de les stocker dans
une base de données. Le module shelvefournit une interface simple pour pickler et dépickler des objets
dans des fichiers de bases de données de style DBM.
Note: Le module pickle est plutôt lent. Une
réimplémentation du même algorithme en C, qui est jusqu'à 1000 fois
plus rapide, est disponible dans le module cPickle. Il a la même interface sauf que
Pickler et Unpickler sont des fonctions usine, pas
des classes (elles ne peuvent donc pas servir de classes de base
pour l'héritage).
Bien que le module pickle puisse utiliser le module
intégré marshal en interne,
il diffère de marshal en ce sens qu'il gère certains
types de données:
Le format de données utilisé par pickle est propre à Python. Ceci
a pour avantage qu'il n'y a aucune restriction imposée par des standards
externes tels que XDR
(qui ne peut pas représenter le partage de pointeurs); cependant cela
signifie que des programmes qui ne sont pas écrits en Python peuvent
ne pas être capables de reconstituer des objets Python sérialisés.
Par défaut, le format de données de pickle utilise une
représentation ASCII imprimable. C'est un peu plus volumineux qu'une
représentation binaire. Le gros avantage d'utiliser de l'ASCII
imprimable (et d'autres caractéristiques de la représentation utilisée
par pickle) est que pour le débogage ou la récupération de
données il est possible pour un humain de lire le fichier picklé
avec un éditeur de texte standard.
Un format binaire, qui est légèrement plus efficace, peut être choisi en
spécifiant une valeur différente de zéro (vraie) pour l'argument
bin du constructeur de Pickler ou des fonctions
dump() et dumps(). Le format binaire n'est
pas le format par défaut pour rester compatible avec le module pickle
de Python 1.4. Dans une version future il est possible que la
valeur par défaut corresponde au format binaire.
Le module pickle ne gère pas les objets code, ce que fait le
module marshal. Je suppose que
pickle pourrait le faire, et peut-être le devrait-il, mais il
n'y en a pas un grand besoin dans l'immédiat (aussi longtemps que
marshal continue de servir à lire et écrire des objets
code), et au moins cela évite la possibilité de faire entrer subrepticement
des chevaux de Troie dans un programme.
A l'attention des modules de persistence écrits en se servant de
pickle, il supporte la notion de référence à un objet en-dehors
du flux de données picklées. De tels objets sont référencés par un nom,
qui est une chaîne arbitraire de caractères ASCII imprimables.
La résolution de tels noms n'est pas définie par le module pickle -
le module d'objets persistants devra implémenter une méthode
persistent_load(). Pour écrire des références à des objets
persistants, le module persistant doit définir une méthode
persistent_id() qui retourne soit Il y a quelques restrictions au picklage des instances de classes.
D'abord, la classe doit être définie au niveau supérieur dans un module.
En outre, toutes ses variables d'instances doivent être picklable.
Quand une instance de classe picklée est dépicklée, sa méthode
__init__() n'est normalement pas invoquée.
Note: Ceci constitue une évolution par rapport aux
versions précédentes de ce module; le changement a été introduit en
Python 1.5b2. La raison du changement est que dans beaucoup de cas il
est souhaitable d'avoir un constructeur qui requiert des arguments;
c'est un inconvénient (mineur) d'avoir à fournir une méthode
__getinitargs__().
S'il est souhaitable que la méthode __init__() soit
appelée au moment du dépicklage, une classe doit définir une
méthode __getinitargs__(), qui doit retourner un
tuple contenant les arguments qui doivent être passés
au constructeur de la classe (__init__()). Cette méthode
est appelée au moment du picklage; le tuple qu'il retourne est
incorporé dans le pickle de l'instance.
Les classes peuvent influencer plus profondément la façon dont leurs
instances sont picklées - si la classe
définit la méthode __getstate__(), elle est appelée et l'état de
retour est picklé comme le contenu de l'instance, et si la classe
définit la méthode __setstate__(), elle est appelée avec l'état
dépicklé. (Notez que ces méthodes peuvent aussi servir à implémenter
la copie des instances de classes.) S'il n'y a pas de méthode
__getstate__(), le __dict__ de l'instance est
picklé. S'il n'y a pas de méthode __setstate__(), l'objet
picklé doit être un dictionnaire et ses éléments sont affectés au
dictionnaire de la nouvelle instance. (Si une classe définit à la fois
__getstate__() et __setstate__(), l'objet état n'a
pas besoin d'être un dictionnaire - ces méthodes peuvent faire ce qu'elles
veulent.) Ce protocole est aussi utilisé par les opérations de copie
superficielle et profonde définies dans le module
copy.
Notez que quand des instances de classes sont picklées, le code et
les données de la classe ne sont pas picklées en même temps qu'elles.
Seules les données d'instances sont picklées. Ceci est fait
volontairement, pour que vous puissiez corriger des bogues dans une
classe ou ajouter des méthodes et continuer de charger des objets
qui ont été créés avec une version précédente de la classe.
Si vous prévoyez de conserver longtemps des objets qui verront
de nombreuses versions de la classe, il peut valoir le coup de
mettre un numéro de version dans les objets de façon que les
conversions adéquates puissent être faites par la méthode
__setstate__() de la classse.
Quand une classe elle-même est picklée, seul son nom est picklé - la
définition de la classe n'est pas picklée, mais réimportée par le
processus de dépicklage. Par conséquent, la restriction qui impose
que la classe soit définie au niveau supérieur dans un module s'applique
aussi aux classes picklées.
L'interface peut être résumée de la façon suivante:
Pour pickler un objet Ou, en raccourci:
Pour dépickler un objet En raccourci:
La classe Pickler ne fait qu'appeler la méthode Le constructeur de la classe Pickler possède un second argument
optionnel, bin. S'il est présent et vrai, le format de picklage
binaire est utilisé; s'il est absent ou faux, le format de picklage
texte (moins efficace, mais garantissant la compatibilité ascendante)
est utilisé. La classe Unpickler ne possède pas d'argument pour
distinguer entre les formats binaire et texte; il accepte les deux
formats.
Les types suivants peuvent être picklés:
Les tentatives de pickler des objets impicklables déclenchent
l'exception PicklingError; quand ceci se produit, un
nombre indéterminé d'octets peut avoir été écrit dans le fichier.
Il est possible de réaliser des appels multiples à la méthode
dump() de la même instance de Pickler. Ils doivent
alors correspondre au même nombre d'appels de l'instance de
Unpickler correspondante. Si le même objet est picklé par
plusieurs appels à dump(), les appels à load()
produiront tous des références vers le même objet.
Avertissement: ceci est prévu pour pickler plusieurs objets
sans que ces objets ou leurs parties aient subi des modifications.
Si vous modifiez un objet et qu'ensuite vous le repicklez en vous
servant de la même instance de Pickler, l'objet n'est pas
repicklé - c'est une référence vers lui qui est picklée, et
Unpickler retournera la vieille valeur, pas celle qui a
été modifiée.
(Deux problèmes ici: (a) détecter les changements, et (b)
marshaller un ensemble minimal de changements. Je n'ai pas de
réponse. Le ramassage de miettes peut aussi devenir un problème dans
ce cas.)
A part les classes Pickler et Unpickler, le module
définit les fonctions suivantes, et une exception:
Voir aussi: None, soit l'ID
persistant de l'objet.
x vers un fichier f, ouvert en écriture:
p = pickle.Pickler(f)
p.dump(x)
pickle.dump(x, f)
x depuis un fichier f, ouvert en lecture:
u = pickle.Unpickler(f)
x = u.load()
x = pickle.load(f)
f.write()
avec un argument chaîne.
La classe Unpickler appelle la méthode f.read()(avec un argument entier) et f.readline() (sans argument),
tous deux retournant une chaîne de caractères. Il est explicitement
autorisé de passer des objets non fichiers ici, tant qu'ils ont les bonnes
méthodes.
Nonedump(objet, fichier[, bin])
load(fichier)
dumps(objet[, bin])
loads(chaine)
PicklingError
Sous-sections