python - 从旧样式转换为新样式后是否可以 Unpickle 类实例?

标签 python inheritance pickle

在 python 中,是否可以在转换为新型 python 类后取消 pickle 对象? (即,具有不同“类签名”的对象)。 *

例如,假设一些实例被保存为:

class foo: # old style

然后在将类更改为从对象继承之后又 pickle 了一些对象:

class foo(object): # new style

用一个pickle.dump'ed 的对象可以用相同的样式类pickle.load'ed,但是没有一个会加载两个。我认为 pickle 使用的策略会根据继承而变化(从 object 继承的类有一个自动定义的 __reduce__ 方法,但没有继承的类没有)。当尝试从没有继承(旧式定义)的代码加载具有继承性的旧式 pickle 时,我得到了与此 SO question 中看到的相同的参数错误。 ;即使第二个参数是多余的,它仍然会更改“类签名”和预期参数,并阻止加载。为了解决这个问题,我很乐意写一个 unpickler,尽管恐怕它可能涉及两个单独的子类 unpickler a la the docs ......如果我知道如何正确地解开每一个,我就可以做到这一点。

关于我的情况的一些背景知识...我正在使用 TrialHandler 类来保存和重新加载行为心理学实验的按钮按下和 react 时间。我们重构了 TrialHandler 类以从更抽象的 baseTrialHandler 继承,但这样做临时更改了类签名以从 object 继承。但是,我们无法解开较旧的 trial_handler 文件,因此将其改回。我想查看使用两个版本的试验处理程序运行的同一实验的数据,因此想在同一脚本中取消选择两种类型的已保存日志文件。

或者,如果我不能编写一个自定义的 unpickler 来 unpickle 两个对象,是否有另一种方法来序列化它们?我尝试直接转储到 yaml,但看起来我必须将该类注册为可以被 yaml 化的东西,无论如何。

一个完整的description of the problem特定错误在 PsychoPy 邮件列表中。欢迎任何解释中间 pickling 甚至 python 继承细节的博客文章;我找到的最接近的很好地解释了为什么 pickling is insecure将 pickling 描述为“简单的基于堆栈的虚拟机”,这很好,但还不足以让我自己弄清楚 unpicking 的基本知识。

最佳答案

遍历部分:

  1. Python 中没有所谓的“类签名”,尽管我 从你的问题中得到灵感
  2. 在 Python 2 程序中不继承“对象”应该是 认为是一个错误。不从对象继承的类 - 也 称为“旧式”类(class),其中只保留语言 向后兼容性,当引入新样式类时 Python 2.2(大约 2000/2001 年)——旧式类少了很多 一致且缺乏许多使今天的 python 如此的特性 漂亮的语言。

除此之外:unpickle 将尝试根据类限定名称反序列化对象 - 如 <module>.<class> ,就像在对象的 __class__.__name__ 上一样 pickle 时间的属性。所以有可能有一种天真的方法,即在 unpickle 异常(它引发 TypeError)时,交换具有相同名称的可用类,然后重试 unpickle 操作 同样:你的类应该继承自“object”(更具体地说,有一个基于“type”的元类)

至于我举的例子,随便写点东西吧:

try:
    new_obj = pickle.load(data_stream)
except TypeError: # if you know this was caused due to the new version of "Foo" class:
    current_foo = foomodule.Foo
    foomodule.Foo = foomodule.OldFoo
    new_obj = pickle.load(data_stream)
    foomodule.Foo = current_foo

关于python - 从旧样式转换为新样式后是否可以 Unpickle 类实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10036565/

相关文章:

python - 优化matplotlib pyplot : plotting for many small plots

java - 如何将 Java 作用域限制为子类?

inheritance - 关于UML类图中关联类的问题

c++ - 如果我将派生指针转换为基指针,是否保证这两个指针具有相同的值?

python - 当 RDD 包含用户定义的类时,为什么 Apache PySpark top() 会失败?

python - 在 Python 中加速一对多相关性计算

python - Spacy 中的自定义句子分割

python - 使用多处理时无法 pickle 静态方法

python - 使用 joblib 加载 pkl 文件时出错

python - Pandas 重采样跳过时间序列的第一个日期