在对Python pickle: dealing with updated class definitions的回答中,dill
包的作者写道:
“好的,我已经在github的最新版本中向dill添加了这个特性。用远比我想象的要少的诡计来实现。。。只要用pickle序列化类定义,就可以了。”
安装了dill
并对其进行了修改之后,我不清楚如何在dill
中实际使用此功能。有人能提供一个明确的例子吗?我希望pickle类实例并序列化类定义。
(我是python新手,这个功能看起来非常重要,因为当挑选一个对象时,最好尽可能接近一个保证,在类定义发生更改并且您没有跟踪一种容易接近的方式。)
我想您正在寻找以下功能之一
在这里,我构建一个类和一个实例,然后更改类定义。 pickled类和实例仍然是不可picklable的,因为
dill
pickles 默认情况下类的源代码…并管理有几个类 在命名空间中使用相同的名称(它只是通过管理指针 对类定义的引用)。泡菜会在上面爆炸。如果您不希望
dill
显式序列化类,并且不希望pickle
做什么,那么您可以要求dill
通过引用dill.dumps(Foo, byref=True)
来pickle。或者,可以使用ignore=False
(默认值)动态决定忽略新定义的类。现在,在下面的例子中,我们使用新的类定义,并提取源 从对象中,然后将其保存到文件中。另外,我们可以将源文件转储到一个文件中(这里我使用一个临时文件),以便以后可以导入它。
我希望这会有帮助。
如果这个功能如此重要的话,那么它现在就在语言核心中了。:-) 所以,不,在任何高级形式下使用Python都不是很重要——如果您有一个依赖于能够重新实例化基于旧模型的对象的项目——这是可能的,那么您必须仔细考虑它,并且可能将旧模型保留在显式代码中,而不是序列化。
我的建议是“把它分开”,直到你认为你真的需要它,并将它与其他解决方案进行了比较,比如一个强大的模型迁移策略。
也就是说,我试过dill,它的工作原理和广告一样:它可以序列化一个类 就像pickle可以使用“dump”和“dumps”调用处理普通对象一样,用“load”和“loads”重新构建类对象。
可能让您感到困惑的是,序列化对象(通过pickle或dill等)既不包括其源代码(即用于定义类的文本Python代码的实际行数),也不包括其名称。
因此,如果一个类被命名为“a”,那么当它被序列化时,如果在“取消填充”之后需要这个名称,那么必须在全局名称空间中重新将这个名称分配给它。它的原始名称保留在它的
__name__
属性中。(对于同一个模型的多个版本一起生活,这会导致很多冲突)。因此:
相关问题 更多 >
编程相关推荐