python - dumps - ¿Cómo puedo usar pickle para guardar un dict?
modulo shelve python (8)
En general, decapar un dict
fallará a menos que solo tenga objetos simples, como cadenas y enteros.
Python 2.7.9 (default, Dec 11 2014, 01:21:43)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from numpy import *
>>> type(globals())
<type ''dict''>
>>> import pickle
>>> pik = pickle.dumps(globals())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
Pickler(file, protocol).dump(obj)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
save(v)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 306, in save
rv = reduce(self.proto)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can''t pickle %s objects" % base.__name__
TypeError: can''t pickle module objects
>>>
Incluso un dict
muy simple a menudo fallará. Solo depende de los contenidos.
>>> d = {''x'': lambda x:x}
>>> pik = pickle.dumps(d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
Pickler(file, protocol).dump(obj)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
save(v)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global
(obj, module, name))
pickle.PicklingError: Can''t pickle <function <lambda> at 0x102178668>: it''s not found as __main__.<lambda>
Sin embargo, si usa un mejor serializador como dill
o cloudpickle
, la mayoría de los diccionarios se pueden conservar en escabeche:
>>> import dill
>>> pik = dill.dumps(d)
O si quieres guardar tu dict
en un archivo ...
>>> with open(''save.pik'', ''w'') as f:
... dill.dump(globals(), f)
...
El último ejemplo es idéntico a cualquiera de las otras buenas respuestas publicadas aquí (que además de descuidar la capacidad de picking del contenido del dict
es bueno).
He revisado la información que proporcionan los Python , pero todavía estoy un poco confundido. ¿Alguien podría publicar un código de muestra que escribiría un nuevo archivo y luego usar pickle para volcar un diccionario en él?
He encontrado el decapado confuso (posiblemente porque soy grueso). Descubrí que esto funciona, sin embargo:
myDictionaryString=str(myDictionary)
Que luego puedes escribir en un archivo de texto. Dejé de intentar usar Pickle ya que recibía errores que me indicaban que escribiera números enteros en un archivo .dat. Me disculpo por no usar Pickle.
Prueba esto:
import pickle
a = {''hello'': ''world''}
with open(''filename.pickle'', ''wb'') as handle:
pickle.dump(a, handle, protocol=pickle.HIGHEST_PROTOCOL)
with open(''filename.pickle'', ''rb'') as handle:
b = pickle.load(handle)
print a == b
Si solo desea almacenar el dict en un solo archivo, use pickle
así
import pickle
a = {''hello'': ''world''}
with open(''filename.pickle'', ''wb'') as handle:
pickle.dump(a, handle)
with open(''filename.pickle'', ''rb'') as handle:
b = pickle.load(handle)
Si desea guardar y restaurar varios diccionarios en varios archivos para almacenar en caché y almacenar datos más complejos, use cualquier anycache . Hace todas las otras cosas que necesitas alrededor de pickle
from anycache import anycache
@anycache(cachedir=''path/to/files'')
def myfunc(hello):
return {''hello'', hello}
Anycache almacena los diferentes resultados de myfunc
función de los argumentos a diferentes archivos en cachedir
y los vuelve a cargar.
Consulte la documentación para más detalles.
# Save a dictionary into a pickle file.
import pickle
favorite_color = {"lion": "yellow", "kitty": "red"} # create a dictionary
pickle.dump(favorite_color, open("save.p", "wb")) # save it into a file named save.p
# -------------------------------------------------------------
# Load the dictionary back from the pickle file.
import pickle
favorite_color = pickle.load(open("save.p", "rb"))
# favorite_color is now {"lion": "yellow", "kitty": "red"}
>>> import pickle
>>> with open("/tmp/picklefile", "wb") as f:
... pickle.dump({}, f)
...
normalmente es preferible usar la implementación de cPickle
>>> import cPickle as pickle
>>> help(pickle.dump)
Help on built-in function dump in module cPickle:
dump(...)
dump(obj, file, protocol=0) -- Write an object in pickle format to the given file.
See the Pickler docstring for the meaning of optional argument proto.
import pickle
dictobj = {''Jack'' : 123, ''John'' : 456}
filename = "/foldername/filestore"
fileobj = open(filename, ''wb'')
pickle.dump(dictobj, fileobj)
fileobj.close()
import pickle
your_data = {''foo'': ''bar''}
# Store data (serialize)
with open(''filename.pickle'', ''wb'') as handle:
pickle.dump(your_data, handle, protocol=pickle.HIGHEST_PROTOCOL)
# Load data (deserialize)
with open(''filename.pickle'', ''rb'') as handle:
unserialized_data = pickle.load(handle)
print(your_data == unserialized_data)
La ventaja de HIGHEST_PROTOCOL
es que los archivos se hacen más pequeños. Esto hace que se deshaga a veces mucho más rápido.
Aviso importante : el tamaño máximo de archivo de pickle es de aproximadamente 2 GB.
Alternativas
- CSV: formato super simple ( leer y escribir )
- JSON: Agradable para escribir datos legibles por humanos; MUY de uso común ( lectura y escritura )
- YAML: YAML es un superconjunto de JSON, pero más fácil de leer ( leer y escribir , comparación de JSON y YAML )
- pickle: un formato de serialización de Python ( lectura y escritura )
- MessagePack ( paquete de Python ): representación más compacta ( lectura y escritura )
- HDF5 ( paquete de Python ): agradable para matrices ( leer y escribir )
- XML: existe también * suspiro * ( read y write )
Para su aplicación, lo siguiente puede ser importante:
- Soporte por otros lenguajes de programación
- Rendimiento de lectura / escritura
- Compacidad (tamaño del archivo)
Ver también: Comparación de formatos de serialización de datos
En caso de que esté buscando una forma de crear archivos de configuración, puede que quiera leer mi breve artículo Archivos de configuración en Python