从旧样式转换为新样式后是否可以取消拾取类实例?

2024-09-29 21:32:16 发布

您现在位置:Python中文网/ 问答频道 /正文

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

例如,假设某些实例保存为:

class foo: # old style

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

^{pr2}$

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

关于我的情况。。。我正在使用一个TrialHandler类来保存和重新加载按钮按下和行为心理学实验的反应时间。我们重构了TrialHandler类以从更抽象的baseTrialHandler继承,但在这样做时,临时将类签名更改为从对象继承。但是,我们无法解压旧的trial_处理程序文件,所以它被改回来了。我想查看同一个实验的数据,这个实验是用两个版本的试用处理程序运行的,所以我想在同一个脚本中取消对两种类型的保存日志文件的拾取。在

或者,如果我不能编写一个自定义的解压器来解压两个对象,有没有其他方法来序列化它们?我试着直接向yaml转储,但是看起来我必须将类注册为可以yaml'ized的东西。在

带有特定错误的完整description of the problem在精神病邮件列表中。任何解释中间pickling,甚至python继承的详细信息的博客文章都是非常受欢迎的;我发现的最接近的一篇文章解释了为什么pickling is insecure将pickling描述为“基于堆栈的简单虚拟机”,这很好,但是我没有足够的能力去理解自己取消pickling的基础知识。在


Tags: 文件the对象方法处理程序yaml参数定义
1条回答
网友
1楼 · 发布于 2024-09-29 21:32:16

通过零件:

  1. 在Python中没有所谓的“类签名”,尽管我 从你的问题中得到了这个想法
  2. 不是从python2程序中的“object”继承 被认为是个错误。不从对象继承的类 所谓的“旧式”课就是在这里继续讲语言 向后兼容性,当新样式类引入 Python2.2(大约2000/2001年)-旧风格的类要少得多 一致性和缺乏许多特性使得今天的python 不错的语言。在

这样就可以了:unpickle将尝试基于类限定名反序列化对象,就像在<module>.<class>中那样,就像在pickle时对象的__class__.__name__属性一样。因此,可以采用一种简单的方法,在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

相关问题 更多 >

    热门问题