manière plus efficace pour décaper une chaîne
-
22-08-2019 - |
Question
Le module pickle semble utiliser des caractères d'échappement de chaîne lors de décapage; cela devient inefficace par exemple, sur les tableaux numpy. Considérez ce qui suit
z = numpy.zeros(1000, numpy.uint8)
len(z.dumps())
len(cPickle.dumps(z.dumps()))
Les longueurs sont les caractères 1133 et 4249 caractères respectivement.
z.dumps () révèle quelque chose comme "\ x00 \ x00" (zéros réels dans la chaîne), mais cornichon semble utiliser la fonction repr () de la chaîne, ce qui donne "'\ x00 \ x00" (zéros étant ascii zéros).
i.e.. ( "0" dans z.dumps () == False) et ( "0" dans cPickle.dumps (z.dumps ()) == Vrai)
La solution
Essayez d'utiliser une version ultérieure du protocole de conserves au vinaigre avec le paramètre de protocole à pickle.dumps()
. La valeur par défaut est 0 et est un format de texte ASCII. Ceux supérieurs à 1 (je vous suggère d'utiliser pickle.HIGHEST_PROTOCOL). formats de protocole 1 et 2 (et 3 mais c'est pour Py3K) sont binaires et devraient être plus prudents dans l'espace.
Autres conseils
Solution:
import zlib, cPickle
def zdumps(obj):
return zlib.compress(cPickle.dumps(obj,cPickle.HIGHEST_PROTOCOL),9)
def zloads(zstr):
return cPickle.loads(zlib.decompress(zstr))
>>> len(zdumps(z))
128
z.dumps()
est déjà chaîne décapée à-dire, il peut être unpickled utilisant pickle.loads ():
>>> z = numpy.zeros(1000, numpy.uint8)
>>> s = z.dumps()
>>> a = pickle.loads(s)
>>> all(a == z)
True
Une amélioration de la réponse de VarTec, qui semble un peu plus efficace de la mémoire (car il ne force pas tout en une chaîne):
def pickle(fname, obj):
import cPickle, gzip
cPickle.dump(obj=obj, file=gzip.open(fname, "wb", compresslevel=3), protocol=2)
def unpickle(fname):
import cPickle, gzip
return cPickle.load(gzip.open(fname, "rb"))