经过大量搜索,我发现解决我的特定问题的唯一方法是使用动态继承。遵循here的指南和其他一些SO问题非常容易;大多数表是this。
使用第一个链接中的人为示例的修改版本:
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
也无法做到。请参见dill issue #56)
答案 0 :(得分:1)
您可以在模块的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]
在另一个程序执行中,必须至少调用makeinst("MyList", list)
一次,然后才能取消定义类。