web-dev-qa-db-fra.com

Python Choix du protocole de pickle?

J'utilise python 2.7 pour essayer de décaper un objet. Je me demande quelle est la vraie différence entre les protocoles de pickle.

import numpy as np
import pickle
class data(object):
    def __init__(self):
        self.a = np.zeros((100, 37000, 3), dtype=np.float32)

d = data()
print "data size: ", d.a.nbytes/1000000.
print "highest protocol: ", pickle.HIGHEST_PROTOCOL
pickle.dump(d,open("noProt", 'w'))
pickle.dump(d,open("prot0", 'w'), protocol=0)
pickle.dump(d,open("prot1", 'w'), protocol=1)
pickle.dump(d,open("prot2", 'w'), protocol=2)


out >> data size:  44.4
out >> highest protocol:  2

alors j'ai trouvé que les fichiers sauvegardés ont des tailles différentes sur le disque:

  • noProt: 177.6MB
  • prot0: 177,6 Mo
  • prot1: 44,4 Mo
  • prot2: 44,4 Mo

Je sais que prot0 Est un fichier texte lisible par l'homme, donc je ne veux pas l'utiliser. Je suppose que le protocole 0 est celui donné par défaut.

Je me demande quelle est la différence entre les protocoles 1 et 2, y a-t-il une raison pour laquelle je devrais choisir l'un ou l'autre?

Quel est le meilleur à utiliser, pickle ou cPickle?

54
Cobry

De la pickle documentation du format de données du module :

Il existe actuellement 3 protocoles différents pouvant être utilisés pour le décapage.

  • La version 0 du protocole correspond au protocole original ASCII) et est rétrocompatible avec les versions antérieures de Python.
  • La version 1 du protocole est l'ancien format binaire, qui est également compatible avec les versions antérieures de Python.
  • La version 2 du protocole a été introduite dans Python 2.3. Elle fournit un décapage beaucoup plus efficace des classes de style nouveau.

[...]

Si aucun protocole n'est spécifié, le protocole 0 est utilisé. Si le protocole est spécifié en tant que valeur négative ou HIGHEST_PROTOCOL, La version de protocole la plus élevée disponible sera utilisée.

Tenez-vous-en à la version 2 du protocole , en particulier si vous utilisez des classes personnalisées dérivées de object (classes de style nouveau). Quel code le plus moderne fait, ces jours-ci.

À moins que vous ne deviez conserver une compatibilité ascendante avec les anciennes versions de Python), il est plus simple de vous en tenir à la version de protocole la plus élevée sur laquelle vous pouvez mettre la main:

with open("prot2", 'wb') as pfile:
    pickle.dump(d, pfile, protocol=pickle.HIGHEST_PROTOCOL)

Comme il s’agit d’un format binaire, veillez à utiliser 'wb' Comme mode de fichier!

cPickle et pickle sont principalement compatibles; les différences résident dans l'API proposée. Pour la plupart des cas d'utilisation, il suffit de coller avec cPickle; c'est plus rapide. Citant le documentation encore:

Premièrement, cPickle peut être jusqu'à 1000 fois plus rapide que pickle car l'ancien est implémenté en C. Deuxièmement, dans le module cPickle, les callables Pickler() et Unpickler() sont des fonctions, pas des classes. Cela signifie que vous ne pouvez pas les utiliser pour dériver des sous-classes de pickling et de picking personnalisées. La plupart des applications n'ont pas besoin de cette fonctionnalité et devraient bénéficier des performances grandement améliorées du module cPickle.

46
Martijn Pieters

Pour les personnes utilisant Python 3, il existe, à compter de Python 3.5, cinq protocoles possibles parmi lesquels choisir:

Il existe actuellement 5 protocoles différents pouvant être utilisés pour le décapage. Plus le protocole utilisé était élevé, plus la version de Python nécessaire pour lire le cornichon produite) était récente [ doc ]:

  • La version 0 du protocole est le protocole original "lisible par l'homme" et est rétrocompatible avec les versions antérieures de Python.

  • La version 1 du protocole est un ancien format binaire compatible avec les versions antérieures de Python.

  • La version 2 du protocole a été introduite dans Python 2.3. Elle permet un décapage beaucoup plus efficace des classes de style nouveau. Pour plus d'informations sur les améliorations apportées par le protocole 2, reportez-vous au PEP 307.
  • La version 3 du protocole a été ajoutée dans Python 3.0. Il prend explicitement en charge les objets octets et ne peut pas être annoté par Python 2.x. Il s'agit du protocole par défaut, et le protocole recommandé lorsque la compatibilité avec d’autres Python 3 versions est requise.
  • Le protocole version 4 a été ajouté dans Python 3.4. Il prend en charge les objets très volumineux, décape davantage de types d'objets et optimise certains formats de données. Pour plus d'informations sur les améliorations apportées par le protocole 4, reportez-vous au PEP 3154. .

En règle générale, vous devez utiliser le protocole le plus élevé possible, compatible en amont avec ce pour quoi vous souhaitez l'utiliser. Donc, si vous voulez qu’il soit rétrocompatible avec Python 2, la version 2 du protocole est un bon choix si vous voulez qu’il soit rétrocompatible avec tous Python = versions alors la version 1 est bonne. Si vous ne vous souciez pas de la compatibilité ascendante, utilisez pickle.HIGHEST_PROTOCOL vous donne automatiquement le protocole le plus élevé pour votre version Python.

Également dans Python 3, importer pickle importe automatiquement l'implémentation C.

Un autre point à noter en termes de compatibilité est que, par défaut, les protocoles 3 et 4 utilisent le codage Unicode des chaînes, contrairement aux protocoles antérieurs. Donc dans Python 3, si vous chargez un fichier picklé qui a été picklé Python 2, vous devrez probablement spécifier explicitement l'encodage afin de le charger. correctement.

17
patapouf_ai