我已经创建了一个这样的对象:
company1.name = 'banana'
company1.value = 40
我想要保存此对象。我该怎么做呢?
发布于 2014-08-04 20:49:23
我认为假设对象是一个class
是一个非常有力的假设。如果它不是class
呢?还有一个假设是,对象没有在解释器中定义。如果它是在解释器中定义的呢?另外,如果属性是动态添加的呢?当一些python对象在创建后将属性添加到它们的__dict__
中时,pickle
不会考虑添加这些属性(即,它“忘记”它们是被添加的--因为pickle
通过引用对象定义来序列化)。
在所有这些情况下,pickle
和cPickle
都会让你大失所望。
如果您希望保存具有属性(在对象定义中添加或之后添加)的object
(任意创建的)…最好的选择是使用dill
,它可以序列化python中的几乎任何内容。
我们从一个类…开始
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)
...
>>>
现在关机,然后重启...
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
)。
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)
...
>>>
现在读出文件。
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会话,稍后再回来。
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')
>>>
现在关掉你的电脑,去享受一杯浓缩咖啡或者别的什么,然后再回来...
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
获取最新发布的版本。
发布于 2019-11-28 11:26:25
在python3中使用您问题中的company1
的一个简单示例。
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
。
import dill
# Save the file
dill.dump(company1, file = open("company1.pickle", "wb"))
# Reload the file
company1_reloaded = dill.load(open("company1.pickle", "rb"))
发布于 2021-05-11 15:30:08
较新版本的熊猫也有保存泡菜的功能。
我发现这更容易。例如:
pd.to_pickle(object_to_save,'/temp/saved_pkl.pickle' )
https://stackoverflow.com/questions/4529815
复制相似问题