saving - python pickle function
¿Guardar y cargar múltiples objetos en un archivo de pickle? (5)
Daré una demostración orientada a objetos usando pickle
para almacenar y restaurar uno o varios object
:
class Worker(object):
def __init__(self, name, addr):
self.name = name
self.addr = addr
def __str__(self):
string = u''[<Worker> name:%s addr:%s]'' %(self.name, self.addr)
return string
# output one item
with open(''testfile.bin'', ''wb'') as f:
w1 = Worker(''tom1'', ''China'')
pickle.dump(w1, f)
# input one item
with open(''testfile.bin'', ''rb'') as f:
w1_restore = pickle.load(f)
print ''item: %s'' %w1_restore
# output multi items
with open(''testfile.bin'', ''wb'') as f:
w1 = Worker(''tom2'', ''China'')
w2 = Worker(''tom3'', ''China'')
pickle.dump([w1, w2], f)
# input multi items
with open(''testfile.bin'', ''rb'') as f:
w_list = pickle.load(f)
for w in w_list:
print ''item-list: %s'' %w
salida:
item: [<Worker> name:tom1 addr:China]
item-list: [<Worker> name:tom2 addr:China]
item-list: [<Worker> name:tom3 addr:China]
Tengo una clase que sirve a los jugadores en un juego, los crea y otras cosas.
Necesito guardar estos objetos de jugador en un archivo para usarlo más tarde. He intentado con el módulo Pickle, pero no sé cómo guardar varios objetos y volver a cargarlos. ¿Hay alguna manera de hacerlo o debería usar otras clases como listas y guardar y cargar mis objetos en una lista?
¿Hay una mejor manera?
Dos adiciones a la respuesta aceptada de Tim Peters .
En primer lugar , no necesita almacenar la cantidad de elementos que seleccionó por separado si deja de cargar cuando llega al final del archivo:
def loadall(filename):
with open(filename, "rb") as f:
while True:
try:
yield pickle.load(f)
except EOFError:
break
items = loadall(myfilename)
Esto supone que el archivo contiene solo pepinillos; si hay algo más allí, el generador tratará de tratar cualquier otra cosa que haya allí como encurtidos, lo que podría ser peligroso.
Segundo , de esta manera, no obtienes una lista, sino un generator . Esto cargará solo un elemento en la memoria a la vez, lo cual es útil si los datos objeto de dumping son muy grandes, una posible razón por la que es posible que haya querido agrupar varios elementos por separado en primer lugar. Todavía puede iterar sobre items
con un bucle for
como si fuera una lista.
Es fácil si usa klepto
, que le da la capacidad de almacenar objetos de forma transparente en archivos o bases de datos. Utiliza una API dict y le permite dump
y / o load
entradas específicas de un archivo (en el caso siguiente, los objetos serializados almacenan una entrada por archivo en un directorio llamado scores
).
>>> import klepto
>>> scores = klepto.archives.dir_archive(''scores'', serialized=True)
>>> scores[''Guido''] = 69
>>> scores[''Fernando''] = 42
>>> scores[''Polly''] = 101
>>> scores.dump()
>>> # access the archive, and load only one
>>> results = klepto.archives.dir_archive(''scores'', serialized=True)
>>> results.load(''Polly'')
>>> results
dir_archive(''scores'', {''Polly'': 101}, cached=True)
>>> results[''Polly'']
101
>>> # load all the scores
>>> results.load()
>>> results[''Guido'']
69
>>>
Prueba esto:
import pickle
file = open(''test.pkl'',''wb'')
obj_1 = [''test_1'', {''ability'', ''mobility''}]
obj_2 = [''test_2'', {''ability'', ''mobility''}]
obj_3 = [''test_3'', {''ability'', ''mobility''}]
pickle.dump(obj_1, file)
pickle.dump(obj_2, file)
pickle.dump(obj_3, file)
file.close()
file = open(''test.pkl'', ''rb'')
obj_1 = pickle.load(file)
obj_2 = pickle.load(file)
obj_3 = pickle.load(file)
print(obj_1)
print(obj_2)
print(obj_3)
file.close()
Usar una lista, tupla o dict es, de lejos, la forma más común de hacer esto:
import pickle
PIK = "pickle.dat"
data = ["A", "b", "C", "d"]
with open(PIK, "wb") as f:
pickle.dump(data, f)
with open(PIK, "rb") as f:
print pickle.load(f)
Eso imprime:
[''A'', ''b'', ''C'', ''d'']
Sin embargo, un archivo de pickle puede contener cualquier cantidad de pepinillos. Aquí hay un código que produce la misma salida. Pero tenga en cuenta que es más difícil escribir y comprender:
with open(PIK, "wb") as f:
pickle.dump(len(data), f)
for value in data:
pickle.dump(value, f)
data2 = []
with open(PIK, "rb") as f:
for _ in range(pickle.load(f)):
data2.append(pickle.load(f))
print data2
Si haces esto, eres responsable de saber cuántos encuadres hay en el archivo que escribes. El código anterior lo hace recortando primero el número de objetos de lista.