Python-保存对象(数据持久性)
我创建了一个这样的对象:
company1.name = 'banana' company1.value = 40
我想保存该对象。我怎样才能做到这一点?
回答:
你可以使用pickle
标准库中的模块。这是你的示例的基本应用:
import pickleclass Company(object):
def __init__(self, name, value):
self.name = name
self.value = value
with open('company_data.pkl', 'wb') as output:
company1 = Company('banana', 40)
pickle.dump(company1, output, pickle.HIGHEST_PROTOCOL)
company2 = Company('spam', 42)
pickle.dump(company2, output, pickle.HIGHEST_PROTOCOL)
del company1
del company2
with open('company_data.pkl', 'rb') as input:
company1 = pickle.load(input)
print(company1.name) # -> banana
print(company1.value) # -> 40
company2 = pickle.load(input)
print(company2.name) # -> spam
print(company2.value) # -> 42
你还可以定义自己的简单实用程序,如下所示,该实用程序打开文件并向其中写入单个对象:
def save_object(obj, filename): with open(filename, 'wb') as output: # Overwrites any existing file.
pickle.dump(obj, output, pickle.HIGHEST_PROTOCOL)
# sample usage
save_object(company1, 'company1.pkl')
由于这是一个非常受欢迎的答案,因此,我想谈谈一些高级用法主题。
cPickle(或_pickle)与pickle
实际使用该cPickle模块几乎总是可取的,而不是pickle
因为该模块是用C编写的并且速度更快。它们之间有一些细微的差异,但是在大多数情况下它们是等效的,并且C版本将提供非常优越的性能。切换到它再简单不过,只需将import语句更改为此:
import cPickle as pickle
在Python 3中,它cPickle已被重命名_pickle,但是不再需要执行此操作,因为该pickle模块现在可以自动执行此操作-请参阅python 3中的pickle和_pickle有什么区别?。
总结是,你可以使用类似以下内容的代码来确保你的代码在Python 2和3中都可用时始终使用C版本:
try: import cPickle as pickle
except ModuleNotFoundError:
import pickle
pickle可以使用多种不同的特定于Python的格式读写文件,这些格式称为文档中所述的协议,“协议版本0”为ASCII
,因此“易于阅读”。版本> 1
是二进制文件,可用的最高版本取决于所使用的Python版本。默认值还取决于Python
版本。在Python 2
中,默认值是Protocol
版本,但在Python 3.8.1中,它是Protocol版本。在Python 3.x中,该模块已添加,但在Python 2
中不存在。04pickle.DEFAULT_PROTOCOL
幸运的是,pickle.HIGHEST_PROTOCOL
在每个调用中都有一种写法(假设这就是你想要的,并且你通常会这样做),只需使用文字数字-1-类似于通过负索引引用序列的最后一个元素。因此,与其编写:
pickle.dump(obj, output, pickle.HIGHEST_PROTOCOL)
你可以这样写:
pickle.dump(obj, output, -1)
无论哪种方式,如果你创建了一个Pickler用于多个酸洗操作的对象,则只需指定一次协议:
pickler = pickle.Pickler(output, -1)pickler.dump(obj1)
pickler.dump(obj2)
etc...
注意:如果你正在运行不同版本的Python的环境中,则可能需要显式使用(即,硬编码)所有这些协议都可以读取的特定协议编号(较新的版本通常可以读取较早版本产生的文件) 。
虽然泡菜文件可以包含如上述样品中,当有这些数目不详的任何数量的腌制对象的,它往往更容易将其全部保存在某种可变大小的容器,就像一个list,tuple
或dict
写字一次调用即可将它们全部存储到文件中:
tech_companies = [ Company('Apple', 114.18), Company('Google', 908.60), Company('Microsoft', 69.18)
]
save_object(tech_companies, 'tech_companies.pkl')
然后使用以下命令还原列表及其中的所有内容:
with open('tech_companies.pkl', 'rb') as input: tech_companies = pickle.load(input)
主要优点是你无需知道保存了多少个对象实例即可在以后加载它们(尽管如果没有该信息就可以这样做,但它需要一些专门的代码)。请参阅相关问题的答案在pickle文件中保存和加载多个对象?有关执行此操作的不同方法的详细信息。我个人最喜欢@Lutz Prechelt的答案。它适用于此处的示例:
class Company: def __init__(self, name, value):
self.name = name
self.value = value
def pickled_items(filename):
""" Unpickle a file of pickled data. """
with open(filename, "rb") as f:
while True:
try:
yield pickle.load(f)
except EOFError:
break
print('Companies in pickle file:')
for company in pickled_items('company_data.pkl'):
print(' name: {}, value: {}'.format(company.name, company.value))
以上是 Python-保存对象(数据持久性) 的全部内容, 来源链接: utcz.com/qa/431196.html