泡菜:处理更新的类定义 [英] Pickle: dealing with updated class definitions

查看:112
本文介绍了泡菜:处理更新的类定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过重新编译脚本来更新类定义之后,pickle拒绝序列化该类的先前实例化的对象,并显示错误:无法pickle对象:它与"不属于同一对象

After a class definition is updated by recompiling a script, pickle refuses to serialize previously instantiated objects of that class, giving the error: "Can't pickle object: it's not the same object as "

有没有办法告诉泡菜它应该忽略这种情况?要仅按名称标识类,请忽略导致不匹配的任何内部唯一ID?

Is there a way to tell pickle that it should ignore such cases? To just identify classes by name, ignore whichever internal unique ID is causing the mismatch?

我绝对欢迎提出一个替代的等效模块的建议作为答案,该模块可以方便,可靠地解决此问题.

I would definitely welcome as an answer the suggestion of an alternative, equivalent module which solves this problem in a convenient and robust manner.

作为参考,这是我的动机:

For reference, here's my motivation:

我正在创建一个高效,快速的迭代开发环境,在其中可以实时编辑Python脚本.脚本被反复重新编译,但是数据在编译过程中仍然存在.作为生产力目标的一部分,我正在尝试使用pickle进行序列化,以避免为不断变化的数据结构而编写和更新显式序列化代码的成本.

I am creating a high productivity, rapid iteration development environment in which Python scripts are edited live. Scripts are repeatedly recompiled, but data persists across compiles. As part of the productivity goals, I am trying to use pickle for serialization, to avoid the cost of writing and updating explicit serialization code for constantly changing data structures.

大多数情况下,我会序列化内置类型.我小心翼翼地避免在我腌制的类中进行有意义的更改,并且在必要时使用copy_reg.pickle机制对未腌制进行上转换.

Mostly I serialize built-in types. I am careful to avoid meaningful changes in the classes which I pickle, and when necessary I use the copy_reg.pickle mechanism to perform upconversion on unpickle.

即使类定义没有实际更改(或仅以良性方式更改),脚本重新编译也使我根本无法腌制对象.

Script recompilation prevents me from pickling objects at all, even if class definitions have not actually changed (or have only changed in a benign way).

推荐答案

除非您可以解压缩该类定义的早期版本,否则引用pickle需要转储并加载该实例,现在已经不存在了.因此这是不可能的".

Unless you can unpack the earlier version of the class definition, the reference pickle needs to dump and load the instance is now gone. So this is "not possible".

但是,如果您确实想这样做,则可以保存您的类定义的早期版本...然后您将不得不使泡菜去指代您的旧的/保存的类定义,而不使用最新的类定义-这可能只相当于编辑obj.__class__obj.__module__指向您的旧类.您的类实例中可能还存在其他一些奇怪的事情,这些事情也引用了您必须处理的旧类定义.此外,如果添加或删除类方法,则可能会遇到一些意外结果,或者必须处理相应的实例更新.另一个有趣的变化是,您可以使取消选择程序始终使用班级的最新版本.

However, if you did want to do it, you could save previous versions of your class definitions... and then it would just be that you'd have to trick pickle into referring to your old/saved class definitions, and not using the most current ones -- which might just amount to editing obj.__class__ or obj.__module__ to point to your old class. There may also be some other odd things in your class instance that also refer to the old class definition that you'd have to handle. Also, if you add or delete a class method, you may run in to some unexpected results, or have to deal with updating the instance accordingly. Another interesting twist is that you could make the unpickler always use the most current version of your class.

我的序列化程序包 dill 有一些方法可以将编译后的源代码从实时代码对象转储到临时对象文件,然后使用该临时文件进行序列化.它是该软件包的较新部分之一,因此不像其他莳萝一样健壮.另外,您的用例不是我考虑过的用例,但是我可以看到它是一个不错的功能.

My serialization package, dill, has some methods that can dump compiled source from a live code object to a temporary file, and then serialize using that temporary file. It's one of the newer parts of the package, so it's not as robust as the rest of dill. Also, your use case is not a use case I'd considered, but I could see how it would be a nice feature to have.

这篇关于泡菜:处理更新的类定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆