Sérialisation Python - Pourquoi pickle?

87

J'ai compris que le pickling Python est un moyen de `` stocker '' un objet Python d'une manière qui respecte la programmation d'objets - différente d'une sortie écrite dans un fichier txt ou une base de données.

Avez-vous plus de détails ou de références sur les points suivants:

  • où les objets marinés sont-ils «stockés»?
  • Pourquoi le décapage préserve-t-il davantage la représentation des objets que, par exemple, le stockage dans DB?
  • puis-je récupérer des objets marinés d'une session Python shell à une autre?
  • avez-vous des exemples significatifs où la sérialisation est utile?
  • la sérialisation avec pickle implique-t-elle une «compression» des données?

En d'autres termes, je recherche un document sur le pickling - Python.doc explique comment implémenter pickle mais ne semble pas plonger dans les détails sur l'utilisation et la nécessité de la sérialisation.

Kiriloff
la source
Pour enregistrer l'état pour une restauration ultérieure ou pour partager / copier un objet dans un autre environnement d'exécution Python, je suppose.
synthesizerpatel
13
L'article de Wikipédia sur la sérialisation répond à plusieurs de vos questions: en.wikipedia.org/wiki/Serialization
NPE
5
demandez-vous pourquoi aurais-je besoin de Pickle pour la sérialisation en Python? ou plutôt quel est (le but de) la sérialisation après tout? .
moooeeeep
Peut-être bon de mentionner les problèmes de sécurité liés au cornichon. Des exemples peuvent être trouvés dans la documentation et dans de nombreuses questions SO, comme celle-ci .
djvg le

Réponses:

99

Le décapage est un moyen de convertir un objet python (liste, dict, etc.) en un flux de caractères. L'idée est que ce flux de caractères contient toutes les informations nécessaires pour reconstruire l'objet dans un autre script python.

Quant à l'endroit où les informations marinées sont stockées, on ferait généralement:

with open('filename', 'wb') as f:
    var = {1 : 'a' , 2 : 'b'}
    pickle.dump(var, f)

Cela stockerait la version picklée de notre vardict dans le fichier 'filename'. Ensuite, dans un autre script, vous pourriez charger à partir de ce fichier dans une variable et le dictionnaire serait recréé:

with open('filename','rb') as f:
    var = pickle.load(f)

Une autre utilisation du décapage est si vous devez transmettre ce dictionnaire sur un réseau (peut-être avec des sockets ou quelque chose). Vous devez d'abord le convertir en un flux de caractères, puis vous pouvez l'envoyer via une connexion socket.

De plus, il n'y a pas de "compression" à proprement parler ici ... c'est juste un moyen de passer d'une représentation (en RAM) à une autre (en "texte").

About.com a une belle introduction au décapage ici .

austin1howard
la source
2
généralement on feraitwith open('filename') as f: ...
moooeeeep
3
En outre, vous devrez faire with open(filename, 'wb') as f: ...ou vous ne pourriez pas écrire dans le fichier.
Tim Pietzcker
Merci!! Celui-ci sur la gestion de la persistance Python est sympa, ici
kiriloff
1
En général, ce n'est pas une très bonne idée à utiliser picklepour transmettre un dictionnaire sur un réseau (json pourrait être mieux ici). Bien que dans de rares cas, cela puisse être utile, par exemple, multiprocessingmodule.
jfs
@Tim Pietzcker: protocol=0(par défaut sur Python2.x) peut être utilisé avec les fichiers ouverts en mode texte.
jfs
36

Le décapage est absolument nécessaire pour le calcul distribué et parallèle.

Supposons que vous vouliez effectuer une réduction de mappage parallèle avec multiprocessing(ou entre les nœuds de cluster avec pyina ), vous devez vous assurer que la fonction que vous souhaitez mapper sur les ressources parallèles sera pickle. Si elle ne décaper pas, vous ne pouvez pas l' envoyer aux autres ressources sur un autre processus, ordinateur, etc. Voir aussi ici pour un bon exemple.

Pour ce faire, j'utilise l' aneth , qui peut sérialiser presque tout en python. Dill dispose également de bons outils pour vous aider à comprendre ce qui cause l'échec de votre décapage lorsque votre code échoue.

Et, oui, les gens utilisent le picking pour enregistrer l'état d'un calcul, ou votre session ipython , ou autre. Vous pouvez également étendre Pickler et UnPickler de pickle pour effectuer la compression avec bz2ou gzipsi vous le souhaitez.

Mike McKerns
la source
0

Je trouve cela particulièrement utile avec des classes personnalisées volumineuses et complexes. Dans un exemple particulier auquel je pense, "Rassembler" les informations (à partir d'une base de données) pour créer la classe représentait déjà la moitié de la bataille. Ensuite, ces informations stockées dans la classe peuvent être modifiées au moment de l'exécution par l'utilisateur.

Vous pouvez avoir un autre groupe de tables dans la base de données et écrire une autre fonction pour parcourir tout ce qui est stocké et l'écrire dans les nouvelles tables de la base de données. Ensuite, vous devrez écrire une autre fonction pour pouvoir charger quelque chose de sauvegardé en lisant toutes ces informations.

Vous pouvez également sélectionner la classe entière telle quelle, puis la stocker dans un seul champ de la base de données. Ensuite, lorsque vous allez le recharger, tout se rechargera en même temps comme avant. Cela peut finir par économiser beaucoup de temps et de code lors de l'enregistrement et de la récupération de classes compliquées.

Poulet Max
la source
-1

c'est une sorte de sérialisation. utilisez cPickle c'est beaucoup plus rapide que pickle.

import pickle
##make Pickle File
with open('pickles/corups.pickle', 'wb') as handle:
    pickle.dump(corpus, handle)

#read pickle file
with open('pickles/corups.pickle', 'rb') as handle:
    corpus = pickle.load(handle)
Paritosh Yadav
la source