顶级课程可以被腌制和打开(文档错误吗?)

时间:2015-12-16 14:00:33

标签: python pickle

下面链接的文档似乎说顶层类可以被腌制,以及它们的实例。但根据我之前的question的答案,它似乎不正确。在我发布的脚本中,pickle接受了类对象并写了一个文件,但这没用。

这是我的问题:这个文档是错误的,还是有些更微妙的我不明白?此外,在这种情况下,pickle应该生成某种错误消息吗?

https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled

  

可以腌制以下类型:

     
      
  • 无,真,假
  •   
  • 整数,长整数,浮点数,复数
  •   
  • 普通和Unicode字符串
  •   
  • 仅包含可选对象的元组,列表,集和词典
  •   
  • 在模块顶层定义的功能
  •   
  • 在模块顶层定义的内置函数
  •   
  • 在模块顶层定义的类我的粗体
  •   
  • 此类的实例 dict 或调用 getstate ()>的结果是可选择的(详见“泡菜协议”一节)。
  •   

2 个答案:

答案 0 :(得分:4)

创建一个在模块顶层定义的类

<强> foo.py

class Foo(object): pass

然后运行一个单独的脚本,

<强> script.py

import pickle
import foo


with open('/tmp/out.pkl', 'w') as f:
    pickle.dump(foo.Foo, f)

del foo

with open('/tmp/out.pkl', 'r') as f:
    cls = pickle.load(f)

print(cls)

打印

<class 'foo.Foo'>

请注意,pickle文件out.pkl仅包含 strings ,它们命名定义模块和类的名称。它不存储类的定义:

cfoo
Foo
p0
.

因此,在取消时,定义模块foo必须包含类的定义。如果从定义模块中删除该类

del foo.Foo

然后你就会收到错误

AttributeError: 'module' object has no attribute 'Foo'

答案 1 :(得分:1)

完全有可能在python中挑选一个类实例...同时还保存代码以重建类和实例的状态。如果你想在pickle之上破解一个解决方案,或者使用&#34;特洛伊木马&#34;这里基于exec的方法是如何做到的:

How to unpickle an object whose class exists in a different namespace (python)?

或者,如果你使用dill,你有一个dump函数已经知道如何存储类实例,类代码和实例状态:

How to recover a pickled class and its instances

Pickle python class instance plus definition

我是dill作者,我创建dill部分是为了能够在multiprocessing之间发送类实例和类方法。

Can't pickle <type 'instancemethod'> when using python's multiprocessing Pool.map()