首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >保存对象(数据持久化)

保存对象(数据持久化)
EN

Stack Overflow用户
提问于 2010-12-25 17:02:04
回答 3查看 317K关注 0票数 309

我已经创建了一个这样的对象:

代码语言:javascript
复制
company1.name = 'banana' 
company1.value = 40

我想要保存此对象。我该怎么做呢?

EN

回答 3

Stack Overflow用户

发布于 2014-08-04 20:49:23

我认为假设对象是一个class是一个非常有力的假设。如果它不是class呢?还有一个假设是,对象没有在解释器中定义。如果它是在解释器中定义的呢?另外,如果属性是动态添加的呢?当一些python对象在创建后将属性添加到它们的__dict__中时,pickle不会考虑添加这些属性(即,它“忘记”它们是被添加的--因为pickle通过引用对象定义来序列化)。

在所有这些情况下,picklecPickle都会让你大失所望。

如果您希望保存具有属性(在对象定义中添加或之后添加)的object (任意创建的)…最好的选择是使用dill,它可以序列化python中的几乎任何内容。

我们从一个类…开始

代码语言:javascript
复制
Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[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.
>>> import pickle
>>> class Company:
...     pass
... 
>>> company1 = Company()
>>> company1.name = 'banana'
>>> company1.value = 40
>>> with open('company.pkl', 'wb') as f:
...     pickle.dump(company1, f, pickle.HIGHEST_PROTOCOL)
... 
>>> 

现在关机,然后重启...

代码语言:javascript
复制
Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[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.
>>> import pickle
>>> with open('company.pkl', 'rb') as f:
...     company1 = pickle.load(f)
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1378, in load
    return Unpickler(file).load()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1090, in load_global
    klass = self.find_class(module, name)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1126, in find_class
    klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'Company'
>>> 

Oops…pickle不能处理它。让我们试试dill。为了更好地衡量,我们将抛出另一个对象类型( lambda)。

代码语言:javascript
复制
Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[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.
>>> import dill       
>>> class Company:
...     pass
... 
>>> company1 = Company()
>>> company1.name = 'banana'
>>> company1.value = 40
>>> 
>>> company2 = lambda x:x
>>> company2.name = 'rhubarb'
>>> company2.value = 42
>>> 
>>> with open('company_dill.pkl', 'wb') as f:
...     dill.dump(company1, f)
...     dill.dump(company2, f)
... 
>>> 

现在读出文件。

代码语言:javascript
复制
Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[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.
>>> import dill
>>> with open('company_dill.pkl', 'rb') as f:
...     company1 = dill.load(f)
...     company2 = dill.load(f)
... 
>>> company1 
<__main__.Company instance at 0x107909128>
>>> company1.name
'banana'
>>> company1.value
40
>>> company2.name
'rhubarb'
>>> company2.value
42
>>>    

它起作用了。pickle失败而dill没有失败的原因是,dill__main__视为模块(在很大程度上),而且还可以通过引用来筛选类定义(就像pickle一样)。dill可以lambda的原因是它为它提供了一个名称…然后酸洗魔法就会发生。

实际上,有一种更简单的方法来保存所有这些对象,特别是当你创建了很多对象的时候。只需转储整个python会话,稍后再回来。

代码语言:javascript
复制
Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[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.
>>> import dill
>>> class Company:
...     pass
... 
>>> company1 = Company()
>>> company1.name = 'banana'
>>> company1.value = 40
>>> 
>>> company2 = lambda x:x
>>> company2.name = 'rhubarb'
>>> company2.value = 42
>>> 
>>> dill.dump_session('dill.pkl')
>>> 

现在关掉你的电脑,去享受一杯浓缩咖啡或者别的什么,然后再回来...

代码语言:javascript
复制
Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[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.
>>> import dill
>>> dill.load_session('dill.pkl')
>>> company1.name
'banana'
>>> company1.value
40
>>> company2.name
'rhubarb'
>>> company2.value
42
>>> company2
<function <lambda> at 0x1065f2938>

唯一的主要缺点是dill不是python标准库的一部分。所以如果你不能在你的服务器上安装一个python包,那么你就不能使用它。

但是,如果您能够在系统上安装python包,则可以使用git+https://github.com/uqfoundation/dill.git@master#egg=dill获得最新的dill。您可以使用pip install dill获取最新发布的版本。

票数 58
EN

Stack Overflow用户

发布于 2019-11-28 11:26:25

在python3中使用您问题中的company1的一个简单示例。

代码语言:javascript
复制
import pickle

# Save the file
pickle.dump(company1, file = open("company1.pickle", "wb"))

# Reload the file
company1_reloaded = pickle.load(open("company1.pickle", "rb"))

然而,正如这篇answer所指出的,pickle经常失败。所以你真的应该使用dill

代码语言:javascript
复制
import dill

# Save the file
dill.dump(company1, file = open("company1.pickle", "wb"))

# Reload the file
company1_reloaded = dill.load(open("company1.pickle", "rb"))
票数 11
EN

Stack Overflow用户

发布于 2021-05-11 15:30:08

较新版本的熊猫也有保存泡菜的功能。

我发现这更容易。例如:

代码语言:javascript
复制
pd.to_pickle(object_to_save,'/temp/saved_pkl.pickle' )
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4529815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档