如何保存对象(数据持久性)?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (72)

我创建了这样一个对象:

company1.name = 'banana' 
company1.value = 40

我想保存这个对象。我该怎么做?

提问于
用户回答回答于

我认为假定对象是a是一个非常强烈的假设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'
>>> 

糟糕...... pickle无法处理它。我们试试吧dill。我们会抛出另一个对象类型(a 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包,你可以得到最新的dillgit+https://github.com/uqfoundation/dill.git@master#egg=dill。你可以用最新版本发布pip install dill

热门问答

怎么使用rsa?

Tina

腾讯云 · 产品经理 (已认证)

Go Serverless!
推荐
您好,可以在在本地安装rsa module后,将依赖一起打zip包上传SCF运行。https://pypi.org/project/rsa/ 在本地做SCF项目的编辑和部署,推荐您使用tcf cli,更加方便高效。 https://github.com/tencentyun/tc...... 展开详请

5.17 更新的备案材料下载是怎么回事?

为了减少下载错误的核验单模板,官网文档中《网站真实性核验单》下载入口已经下掉,可以按照如下方式操作: 1、在备案流程中——上传资料——核验单环节下载 2、在了解备案的省份、单位性质后,可在工单中提供对应省份的核验单模板给到你。 ... 展开详请

域名在腾讯备的案,解析的腾讯云,现在想把域名解析到别商家的服务器,腾讯云会把备案注销吗?

software微软、谷歌、腾讯、阿里、百度……
推荐

接入商都是有责任对备案进行定期核查的,核查中如果客户在腾讯云进行了备案未解析腾讯云服务器是需要重新解析腾讯云服务器的,否则会被取消接入,反之解析了服务器未进行备案各家接入商也是有相应的限制的,比如:腾讯云对未在腾讯云备案的域名会进行未备案阻断。

对象存储COS有没有日志功能?

Hyman Wang

腾讯云 · 高级产品经理 (已认证)

推荐已采纳

你的cos 是否开通了 CDN 加速,如果开通了CDN 加速,可以去 CDN 的控制台下: (统计分析 --- 监控 )页面下拉到底部,可以通过 URL 查看流量情况。

对象存储里的视频能在线播放么?

Jinqn

腾讯 · 高级工程师 (已认证)

腾讯云COS前端开发
推荐

购买的云数据库里面有什么类型的数据库?有SQLserver吗?可以自己安装SQLserver吗?

帅的惊动我国计算机大神
推荐已采纳
云关系型数据库让您在云中轻松部署、管理和扩展的关系型数据库,提供安全可靠、伸缩灵活的按需云数据库服务。腾讯云关系型数据库提供 MySQL、SQL Server、MariaDB、PostgreSQL 数据库引擎,并针对数据库引擎的性能进行了优化。云关系型数据库是一种高度可用的托管服...... 展开详请

所属标签

扫码关注云+社区