pickle
参考 指出 可以腌制的对象集相当有限。事实上,我有一个函数返回一个动态生成的类,我发现我不能 pickle 那个类的实例:
>>> import pickle
>>> def f():
... class A: pass
... return A
...
>>> LocalA = f()
>>> la = LocalA()
>>> with open('testing.pickle', 'wb') as f:
... pickle.dump(la, f, pickle.HIGHEST_PROTOCOL)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
AttributeError: Can't pickle local object 'f.<locals>.A'
这样的对象对于 pickle
来说太复杂了。好的。现在,神奇的是,如果我尝试 pickle 一个类似的对象,但它是派生类的,它就起作用了!
>>> class DerivedA(LocalA): pass
...
>>> da = DerivedA()
>>> with open('testing.pickle', 'wb') as f:
... pickle.dump(da, f, pickle.HIGHEST_PROTOCOL)
...
>>>
这里发生了什么事?如果这很容易,为什么 pickle
使用此解决方法来实现 dump
允许“本地对象”被腌制的方法?
原文由 fonini 发布,翻译遵循 CC BY-SA 4.0 许可协议
我认为您没有仔细阅读 您引用的参考资料。该参考文献还明确指出只有以下对象是可腌制的:
你的榜样
没有在模块的顶层定义类,它在
f()
范围 内定义了一个类。pickle
适用于 _全局类_,不适用于本地类。这会自动使 pickleable 测试失败。DerivedA
是一个全局类,所以一切都很好。至于为什么只有顶级(对你来说是全局的)类和函数不能被腌制,参考文献也回答了这个问题(大胆的我的):
所以你有它。
pickle
仅通过名称引用序列化对象,而不是通过对象中包含的原始指令。这是因为pickle's
工作是序列化 _对象层次结构_,没有别的。