Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在pickle文件中保存和加载多个对象?_Python_Class_Object_Python 3.x_Pickle - Fatal编程技术网

Python 在pickle文件中保存和加载多个对象?

Python 在pickle文件中保存和加载多个对象?,python,class,object,python-3.x,pickle,Python,Class,Object,Python 3.x,Pickle,我有一个职业,在游戏中为玩家服务,创造他们和其他东西 我需要将这些播放器对象保存在一个文件中,以便以后使用。我尝试过pickle模块,但不知道如何保存多个对象并再次加载它们?有没有办法做到这一点,或者我应该使用其他类,如列表,并在列表中保存和加载我的对象 有更好的方法吗?使用列表、元组或dict是目前最常用的方法: import pickle PIK = "pickle.dat" data = ["A", "b", "C", "d"] with open(PIK, "wb") as f:

我有一个职业,在游戏中为玩家服务,创造他们和其他东西

我需要将这些播放器对象保存在一个文件中,以便以后使用。我尝试过pickle模块,但不知道如何保存多个对象并再次加载它们?有没有办法做到这一点,或者我应该使用其他类,如列表,并在列表中保存和加载我的对象


有更好的方法吗?

使用列表、元组或dict是目前最常用的方法:

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)
上面印着:

['A', 'b', 'C', 'd']
但是,pickle文件可以包含任意数量的pickle。下面是生成相同输出的代码。但请注意,书写和理解起来更难:

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
如果你这样做,你就有责任知道你写的文件中有多少腌菜。上面的代码通过首先清除列表对象的数量来实现这一点。

添加两个对象

首先,如果在文件末尾停止加载,则不需要单独存储腌制的项目数:

def loadall(filename):
    with open(filename, "rb") as f:
        while True:
            try:
                yield pickle.load(f)
            except EOFError:
                break

items = loadall(myfilename)
这假设文件只包含pickle;如果里面还有其他东西,发电机也会把里面的东西当作泡菜来处理,这可能会很危险

第二个,这样,您就不会得到一个列表,而是一个列表。 这将一次只将一项加载到内存中,这很有用 如果转储的数据非常大——这可能是您 首先,我想分别腌制多个项目。 您仍然可以使用
for
循环来迭代

列表。

我将给出一个面向对象的演示,使用
pickle
存储和恢复一个或多个
对象

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
类工作者(对象):
定义初始化(自我、姓名、地址):
self.name=名称
self.addr=addr
定义(自我):
string=u'[名称:%s地址:%s]'%(self.name,self.addr)
返回字符串
#输出一项
将open('testfile.bin','wb')作为f:
w1=工人('tom1','China')
腌制垃圾场(w1,f)
#输入一项
将open('testfile.bin','rb')作为f:
w1_restore=pickle.load(f)
“打印”项:%s“%w1\u”
#输出多个项目
将open('testfile.bin','wb')作为f:
w1=工人('tom2','China')
w2=工人('tom3','China')
泡菜倾倒区([w1,w2],f)
#输入多个项目
将open('testfile.bin','rb')作为f:
w_列表=pickle.load(f)
对于w_列表中的w:
“打印”项目列表:%s“%w”
输出:

item: [<Worker> name:tom1 addr:China]
item-list: [<Worker> name:tom2 addr:China]
item-list: [<Worker> name:tom3 addr:China]
项目:[名称:tom1地址:中国]
项目清单:[名称:tom2地址:中国]
项目清单:[名称:tom3地址:中国]

如果您使用
klepot
,它将使您能够在文件或数据库中透明地存储对象,这将非常简单。它使用dict API,并允许您从存档中
转储
和/或
加载
特定条目(在下面的例子中,序列化对象在名为
分数
的目录中为每个文件存储一个条目)

试试这个:

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()

如果您以迭代方式转储它,那么您也必须以迭代方式读取它

您可以运行循环(如图所示)以保持取消勾选行,直到到达文件末尾(此时将引发一个
EOFError

data = []
with open("data.pickle", "rb") as f:
    while True:
        try:
            data.append(pickle.load(f))
        except EOFError:
            break
最小可验证示例

import pickle

# Dumping step
data = [{'a': 1}, {'b': 2}]
with open('test.pkl', 'wb') as f:
    for d in data:
        pickle.dump(d, f)

# Loading step
data2 = []
with open('test.pkl', 'rb') as f:
    while True:
        try:
            data2.append(pickle.load(f))
        except EOFError:
            break

data2
# [{'a': 1}, {'b': 2}]

data == data2
# True

当然,这是基于必须单独对对象进行pickle的假设。您也可以将数据存储为单个对象列表,然后使用单个pickle/unpickle调用(无需循环)

下面是如何使用pickle转储两个(或多个)词典,并将其提取回来:

import pickle

dict_1 = {1: 'one', 2: 'two'}
dict_2 = {1: {1: 'one'}, 2: {2: 'two'}}

F = open('data_file1.pkl', 'wb')
pickle.dump(dict_1, F)
pickle.dump(dict_2, F)
F.close()
=========================================

import pickle

dict_1 = {1: 'one', 2: 'two'}
dict_2 = {1: {1: 'one'}, 2: {2: 'two'}}

F = open('data_file1.pkl', 'rb')
G = pickle.load(F)
print(G)
H = pickle.load(F)
print(H)
F.close()

假设我们在Employee类的文件中保存了对象。以下是从文件中逐个读取所有对象的代码:

 e = Employee()    

with open(filename, 'rb') as a:
    while True:
        try:
            e = pickle.load(a)
            e.ShowRecord()
        except EOFError:
            break    

使用
列表
作为容器似乎是合理的。1年后询问。我们不能将python的搁置库用于相同的任务。如果不是,缺点是什么?你可以用它来检查pickle文件:谢谢,我有你的想法,但我认为多个列表对象可能会导致内存问题&我决定将每个播放器保存在一个单独的文件中,但你认为列出pickle对象会导致内存问题吗?没有足够的信息。有多少人?每个玩家的泡菜有多大?有多少内存可用?如果你有很多玩家,最好合并一个数据库并在其中存储pickle(而不是一步一步地创建自己的数据库)。为什么所有pickle示例都使用二进制模式?二进制文件写入是我的工作尚未触及的一个前沿领域……我对它一无所知,也不知道为什么有人在任何地方使用它。@之所以使用Aerovistae二进制模式,是因为Windows会在文本模式下处理行尾字符。这应该是最重要的答案。请注意调用
load(myfilename)
在迭代结果之前,不会实际加载数据或读取文件。如果要立即加载它们,请使用类似于
list(load(myfilename))
for
循环的方法。这种方法是否会在生成器被垃圾收集之前保持文件句柄打开,从而导致潜在的锁定问题?为了解决这个问题,我们是否应该将
yield
放在
with open()
块之外?当然,这会导致不必要的读取来迭代pickle文件,但我想我更喜欢这种方式,而不是挂起文件句柄。除非我们确定这个方法总是被快速调用到EOF,并且在到达文件末尾时关闭文件。(但如果我们费心生成单个元素,那可能是因为我们不需要取消选中文件中的所有对象。)@Chris:如果迭代器一直使用,打开的
将终止并正确关闭文件。如果它可能不被使用到底,我们通常不会关心打开的文件。如果它可能无法使用到底,我们不喜欢打开的文件,那么,是的,上面的解释
import pickle

dict_1 = {1: 'one', 2: 'two'}
dict_2 = {1: {1: 'one'}, 2: {2: 'two'}}

F = open('data_file1.pkl', 'rb')
G = pickle.load(F)
print(G)
H = pickle.load(F)
print(H)
F.close()
 e = Employee()    

with open(filename, 'rb') as a:
    while True:
        try:
            e = pickle.load(a)
            e.ShowRecord()
        except EOFError:
            break