2011-07-04 8 views
54

Necesito guardar alrededor de una docena de objetos en un archivo y luego restaurarlos más tarde. He intentado usar un bucle for con pickle y shelve pero no funcionó bien.¿Cómo guardo y restauro variables múltiples en python?

Editar.
Todos los objetos que yo estaba tratando de salvar estaban en la misma clase (debería haber mencionado esto antes), y no me había dado cuenta de que solo pudiera salvar a toda la clase como esta:

def saveLoad(opt): 
    global calc 
    if opt == "save": 
     f = file(filename, 'wb') 
     pickle.dump(calc, f, 2) 
     f.close 
     print 'data saved' 
    elif opt == "load": 
     f = file(filename, 'rb') 
     calc = pickle.load(f) 
    else: 
     print 'Invalid saveLoad option' 
+1

Por favor enviar un código de ejemplo – Yossi

+1

Usted dice que ha intentado un bucle. Publique ese código y por qué "no funcionó bien" (es decir, qué sucedió y qué quería que suceda). – Blair

+0

Si está en Windows, asegúrese de abrir los archivos en modo binario –

Respuesta

9

Debería mirar los módulos shelve y pickle. Si necesita almacenar una gran cantidad de datos, puede ser mejor utilizar una base de datos

27

Hay una biblioteca incorporada llamada pickle. Usando pickle puede volcar objetos a un archivo y cargarlos más tarde.

import pickle 

f = open('store.pckl', 'wb') 
pickle.dump(obj, f) 
f.close() 

f = open('store.pckl', 'rb') 
obj = pickle.load(f) 
f.close() 
+1

I Python 3.4 uso: 'f = open ('store.pckl', 'wb')' para abrir un archivo para escribir. Consulte http://stackoverflow.com/questions/13906623/using-pickle-dump-typeerror-must-be-str-not-bytes Y use 'f = open ('store.pckl', 'rb') para abrir un archivo para leer. Consulte http://stackoverflow.com/questions/7031699/typeerror-str-does-not-support-the-buffer-interface. – user3731622

+0

es esto específico para 3.4+? Casi he votado la respuesta porque genera errores cuando no usas 'b'. –

93

Si necesita guardar varios objetos, sólo tiene que ponerlos en una sola lista o tupla, por ejemplo:

import pickle 

# obj0, obj1, obj2 are created here... 

# Saving the objects: 
with open('objs.pkl', 'w') as f: # Python 3: open(..., 'wb') 
    pickle.dump([obj0, obj1, obj2], f) 

# Getting back the objects: 
with open('objs.pkl') as f: # Python 3: open(..., 'rb') 
    obj0, obj1, obj2 = pickle.load(f) 

Si usted tiene una gran cantidad de datos, puede reducir la tamaño de archivo al pasar protocol=-1 a dump(); pickle usará el mejor protocolo disponible en lugar del protocolo histórico predeterminado (y más compatible con versiones anteriores). En este caso, el archivo debe abrirse en modo binario (wb y rb, respectivamente).

El modo binario también se debe utilizar con Python 3, ya que su protocolo predeterminado produce datos binarios (es decir, sin texto) (modo de escritura 'wb' y modo de lectura 'rb').

+4

En Python 3.5, tuve que abrir el archivo en modo "byte", p. 'con open ('objs.pickle', 'wb') como f:' (observe el 'wb'). – kbrose

+1

Buen punto. Lo agregué a la respuesta. – EOL

2

Puede usar klepto, que proporciona el almacenamiento en memoria caché persistente en la memoria, el disco o la base de datos.

[email protected]>$ python 
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[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 klepto.archives import file_archive 
>>> db = file_archive('foo.txt') 
>>> db['1'] = 1 
>>> db['max'] = max 
>>> squared = lambda x: x**2 
>>> db['squared'] = squared 
>>> def add(x,y): 
... return x+y 
... 
>>> db['add'] = add 
>>> class Foo(object): 
... y = 1 
... def bar(self, x): 
...  return self.y + x 
... 
>>> db['Foo'] = Foo 
>>> f = Foo() 
>>> db['f'] = f 
>>> db.dump() 
>>> 

Entonces, después de reiniciar el intérprete ...

[email protected]>$ python 
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[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 klepto.archives import file_archive 
>>> db = file_archive('foo.txt') 
>>> db 
file_archive('foo.txt', {}, cached=True) 
>>> db.load() 
>>> db 
file_archive('foo.txt', {'1': 1, 'add': <function add at 0x10610a0c8>, 'f': <__main__.Foo object at 0x10510ced0>, 'max': <built-in function max>, 'Foo': <class '__main__.Foo'>, 'squared': <function <lambda> at 0x10610a1b8>}, cached=True) 
>>> db['add'](2,3) 
5 
>>> db['squared'](3) 
9 
>>> db['f'].bar(4) 
5 
>>> 

obtener el código aquí: https://github.com/uqfoundation

+0

Esto no está incorporado ... – Zizouz212

+5

El OP no solicitó el built-in. –

Cuestiones relacionadas