我正在使用装饰器扩展某些类并向其添加一些功能,如下所示:
AttributeError: Can't pickle local object 'useful_stuff.<locals>.LocalClass'
不幸的是,由于非全局 LocalClass
, MyClass 不再pickleable{{1}}
答案 0 :(得分:8)
您需要设置元数据,以便子类看起来像原始的:
def deco(cls):
class SubClass(cls):
...
SubClass.__name__ = cls.__name__
SubClass.__qualname__ = cls.__qualname__
SubClass.__module__ = cls.__module__
return SubClass
使用类的模块和质量名对类进行腌制,以记录在何处可以找到该类。如果您的班级没有经过修饰,则需要在与原班级相同的位置找到它,因此,pickle需要看到相同的模块和名称。这类似于funcutils.wraps
对修饰函数所做的操作。
但是,将新方法直接添加到原始类而不是创建子类可能更简单,更不易出错:
def better_foo(self):
print('better_foo')
def useful_stuff(cls):
cls.better_foo = better_foo
return cls