我正在使用多处理模块在Python中进行大量的并行处理。我知道某些对象可能是pickle(因此在multi-p中作为参数传递)而其他对象则不能。例如。
class abc():
pass
a=abc()
pickle.dumps(a)
'ccopy_reg\n_reconstructor\np1\n(c__main__\nabc\np2\nc__builtin__\nobject\np3\nNtRp4\n.'
但是我的代码中有一些较大的类(十几种方法,或者左右),这种情况会发生:
a=myBigClass()
pickle.dumps(a)
Traceback (innermost last):
File "<stdin>", line 1, in <module>
File "/usr/apps/Python279/python-2.7.9-rhel5-x86_64/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle file objects
它不是文件对象,但在其他时候,我会得到其他基本上说的消息:“我不能腌制这个”。
那么规则是什么?字节数?层次深度?月相?
我是 dill
作者。有一个相当全面的清单,其中包括什么泡菜和什么不是 dill
。它可以运行每个版本的python 2.5-3.4,并根据pickles进行调整 dill
或者什么泡菜 pickle
通过改变一个标志。
看这里:
https://github.com/uqfoundation/dill/blob/master/tests/test_objects.py
和
https://github.com/uqfoundation/dill/blob/master/dill/_objects.py。
泡菜的规则的根源(在我的头顶):
- 你能通过引用捕获对象的状态(即a
功能定义于
__main__
与导入功能相比)? [好的]
- 是通用的
__get_state__
__set_state__
给定对象类型是否存在规则? [好的]
- 它取决于a
Frame
对象(即依赖于GIL和全局执行堆栈)?迭代器现在是一个例外,由
在重新打开时“重放”迭代器。 [那就不要]
- 对象实例是否指向错误的类路径(即由于在闭包,C绑定或其他中定义)
__init__
路径操纵)? [那就不要]
- 允许这个被python认为是危险的吗? [那就不要]
因此,(5)现在不像过去那样普遍,但仍然在语言中有一些持久的影响 pickle
。 dill
在大多数情况下,删除(1),(2)和(5) - 但仍然受到(3)和(4)的影响。
我可能会忘记别的东西,但我认为一般来说这些是潜在的规则。
某些模块如 multiprocessing
注册一些对其功能很重要的对象。 dill
在语言中注册大多数对象。
该 dill
叉子 multiprocessing
是必需的,因为 multiprocessing
使用 cPickle
,和 dill
只能增加纯python酸洗注册表。如果你有耐心,你可以通过所有相关的工作 copy_reg
功能 dill
,并将它们应用于 cPickle
模块,你会得到更多的酸洗能力 multiprocessing
。我找到了一个简单的(读取:一个班轮)方式来做到这一点 pickle
, 但不是 cPickle
。
来自 文档:
可以腌制以下类型:
- 无,真,假
- 整数,长整数,浮点数,复数
- 普通和Unicode字符串
- 仅包含可选对象的元组,列表,集和词典
- 在模块顶层定义的函数
- 在模块顶层定义的类
- 这类的实例 字典 或调用的结果 ,有getstate()是可选择的(有关详细信息,请参阅pickle协议一节)。
尝试腌制不可摧毁的对象会引发PicklingError
例外;当发生这种情况时,可能有一个未指定的字节数
已经写入底层文件。试图高度腌制
递归数据结构可能超过最大递归深度,a
在这种情况下将引发RuntimeError。你可以小心地提出这个
sys.setrecursionlimit()限制。
除了icedtrees的回答,也直接来自 文档,您可以使用特殊方法自定义和控制类实例的pickle和unpicked: object.__getnewargs_ex__()
, object.__getnewargs__()
, object.__getstate__()
, object.__setstate__(state)
一般的经验法则是“逻辑”对象可以被腌制,但“资源”对象(文件,锁)不能,因为持久化/克隆它们是没有意义的。