我有一个课程,为游戏中的玩家提供服务,创建他们和其他东西。
我需要将这些播放器对象保存在文件中以便稍后使用。我尝试了pickle模块,但我不知道如何保存多个对象并再次加载它们?有没有办法做到这一点,或者我应该使用其他类,如列表,并保存和加载我的对象列表?
有更好的方法吗?
答案 0 :(得分:87)
Tim Peters' accepted answer的两个补充。
首先,如果在点击文件末尾时停止加载,则无需单独存储您所挑选的商品数量:
def loadall(filename):
with open(filename, "rb") as f:
while True:
try:
yield pickle.load(f)
except EOFError:
break
items = loadall(myfilename)
这假设文件只包含泡菜;如果那里还有其他任何东西,那么发电机也会试着把那里的其他东西当作泡菜来处理,这可能很危险。
第二,这样,你就不会得到一个列表,而是一个generator。
这一次只会将一个项目加载到内存中,这很有用
如果转储的数据非常大 - 可能的原因之一
我们想首先分开腌制多个物品。
您仍然可以使用items
循环迭代for
,就好像它一样
一个清单。
答案 1 :(得分:54)
使用list,tuple或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
如果你这样做,你有责任知道你写的文件中有多少泡菜。上面的代码通过首先挑选列表对象的数量来做到这一点。
答案 2 :(得分:10)
试试这个:
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()
答案 3 :(得分:4)
我将使用pickle
进行面向对象的演示,以存储和恢复一个或多个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
输出:
item: [<Worker> name:tom1 addr:China]
item-list: [<Worker> name:tom2 addr:China]
item-list: [<Worker> name:tom3 addr:China]
答案 4 :(得分:0)
如果使用klepto
,这很容易,这使您能够在文件或数据库中透明地存储对象。它使用dict API,允许您从存档中获取dump
和/或load
个特定条目(在下面的例子中,序列化对象在名为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
>>>
答案 5 :(得分:0)
如果要迭代转储,则还必须迭代阅读。
您可以运行循环(如accepted answer所示),以保持不分页显示行,直到到达文件末尾(此时{{1} })。
EOFError
最小可验证示例
data = []
with open("data.pickle", "rb") as f:
while True:
try:
data.append(pickle.load(f))
except EOFError:
break
当然,这是基于您必须分别对对象进行腌制的假设。您还可以将数据存储为单个对象列表,然后使用单个pickle / unpickle调用(否需要循环)。
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
答案 6 :(得分:0)
这里是如何使用泡菜倾倒两个(或多个字典)并将其提取回去的方法:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="links-block-list">
<li class="primary-list-item"><a href="#">List Item 1</a></li>
<li class="controls-list-item hide"><a href="#">List Item 1</a></li>
<li class="primary-list-item"><a href="#">List Item 2</a></li>
<li class="controls-list-item hide"><a href="#">List Item 2</a></li>
<li class="primary-list-item"><a href="#">List Item 3</a></li>
<li class="controls-list-item hide"><a href="#">List Item 3</a></li>
<li class="primary-list-item"><a href="#">List Item 4</a></li>
<li class="controls-list-item hide"><a href="#">List Item 4</a></li>
<li class="primary-list-item"><a href="#">List Item 5</a></li>
<li class="controls-list-item hide"><a href="#">List Item 5</a></li>
</ul>
======================================
static_assert
答案 7 :(得分:0)
假设我们已将对象保存在Employee类的文件中。这是读取文件中所有对象的代码:
e = Employee()
with open(filename, 'rb') as a:
while True:
try:
e = pickle.load(a)
e.ShowRecord()
except EOFError:
break