可腌制的动态继承?



经过多次搜索,我发现解决特定问题的唯一方法是使用动态继承。遵循此处的指南和其他一些 SO 问题很容易;大多数表是这个。

使用第一个链接中人为示例的修改版本:

def makeinst(cls, *args, **kwargs):
class NewClass(cls): pass
return NewClass(*args, **kwargs)
mylist = makeinst(list,(1,2))

这如我希望的那样有效,但不能腌制:

pickle.dumps(mylist)
...
AttributeError: Can't pickle local object 'makeinst.<locals>.NewClass'

我明白为什么这不起作用,但我想知道有没有办法解决它?有没有更好的方法来动态子类化某些东西?

(FWIW,dill也做不到。见莳萝问题#56(

您可以在模块的global范围内创建类,为此,您需要使用type(name, bases, class_dict)调用手动创建一个类

import pickle
def makeinst(name, cls, *args, **kwargs):
# This will be a method
def foo(self):
return f"I am: {self!r}"
globals()[name] = type(
name,
# This must be a tuple
# (cls) evaluate to cls
# (cls,) evaluates to a tuple containing cls as its only element
(cls,),
# Methods, classmethods, staticmethods and all class-level data
{
"foo": foo
},
)
return globals()[name](*args, **kwargs)
my_list = makeinst("MyList", list, [1, 2, 3])
print(my_list) # [1, 2, 3]
data = pickle.dumps(my_list)
my_list_unpickled = pickle.loads(data)
print(my_list_unpickled) # [1, 2, 3]
print(my_list_unpickled.foo()) # I am: [1, 2, 3]

在另一个程序执行中,您必须在取消 picking 以定义类之前至少调用makeinst("MyList", list)一次。

最新更新