动态类定义的酸洗 [英] Pickling of dynamic class definition

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

问题描述

我正在尝试将动态生成的类作为替代类的工厂进行腌制.类似于以下内容:

I am trying to pickle a dynamically generated class as a factory for an alternative class. Something like the following:

import sys, pickle

class BC(object):
    pass

C = type("NewClassName", (BC,), {})

pickle.dump(C, sys.stdout)

这会导致以下错误:

pickle.PicklingError: Can't pickle <class '__main__.NewClassName'>: it's not found as __main__.NewClassName

为了腌制动态生成的类的对象,您可以定义一个 __reduce__ 方法,但是有没有一种方法可以仅针对类定义来实现这一点.

For pickling an object of a dynamically generated class, you can define an __reduce__ method, but is there a way to achieve this only for a class definition.

我不想直接使用 BC,因为我只需要它作为新类的工厂.

I don't want to use BC directly, because I only need it as a factory for new classes.

推荐答案

该错误的一个简单解决方法是使用类名作为变量名,以便 pickle 可以找到它:

A simple workaround to the error is to use the class name as variable name so that pickle can find it:

import sys, pickle

class BC(object):
    pass

NewClassName = type("NewClassName", (BC,), {})

pickle.dump(NewClassName, sys.stdout)

<小时>

然而,这可能并没有真正做到你想要的.加载pickle类时:


However, this probably doesn't really do what you want. When loading the pickled class:

pickle.loads("""c__main__
NewClassName
p0
.""")

您再次收到错误:

AttributeError: 'module' object has no attribute 'NewClassName'

除非您已经定义了类.

正如文档所述:

pickle 可以透明地保存和恢复类实例,但是类定义必须是可导入的,并且与存储对象时存在于同一模块中.

pickle can save and restore class instances transparently, however the class definition must be importable and live in the same module as when the object was stored.

所以你不能用它来生成新的类,只是为了确保你的对象引用正确的类.

So you can't use it to generate new classes, just to make sure your objects refer to the correct classes.

有一些变通方法,例如酸洗 type 参数,如其他答案所示,但即使那么你将不能在不暴露这些动态类的对象的情况下将类暴露在pickling和unpickling过程的全局命名空间中(即__main__.ClassName必须引用到班级).

There are workarounds like pickling type parameters as shown in the other answer, but even then you will not be able to pickle objects of those dynamic classes without exposing the class in the global namespace of both the pickling and the unpickling process (i.e. __main__.ClassName must refer to the class).

因此,我会重新考虑整个动态类方法.

Therefore, I would rethink the whole dynamic class approach.

这篇关于动态类定义的酸洗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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