[英]Extending a class in Python inside a decorator
I am using a decorator to extend certain classes and add some functionality to them, something like the following: 我正在使用装饰器来扩展某些类并为它们添加一些功能,如下所示:
def useful_stuff(cls):
class LocalClass(cls):
def better_foo(self):
print('better foo')
return LocalClass
@useful_stuff
class MyClass:
def foo(self):
print('foo')
Unfortunaltely, MyClass is no longer pickleable due to the non global LocalClass Unfortunaltely,MyClass的是不再与pickle由于非全球LocalClass
AttributeError: Can't pickle local object 'useful_stuff.<locals>.LocalClass'
You need to set the metadata so the subclass looks like the original: 您需要设置元数据,以便子类看起来像原始的:
def deco(cls):
class SubClass(cls):
...
SubClass.__name__ = cls.__name__
SubClass.__qualname__ = cls.__qualname__
SubClass.__module__ = cls.__module__
return SubClass
Classes are pickled by using their module and qualname to record where to find the class. 通过使用他们的模块和qualname来记录类,以记录在哪里找到类。 Your class needs to be found in the same location the original class would have been if it hadn't been decorated, so pickle needs to see the same module and qualname. 如果没有装饰,你的类需要在原始类所在的位置找到,因此pickle需要查看相同的模块和qualname。 This is similar to what funcutils.wraps
does for decorated functions. 这类似于funcutils.wraps
对装饰函数的作用。
However, it would probably be simpler and less bug-prone to instead add the new methods directly to the original class instead of creating a subclass: 但是,它可能更简单,更不容易出错,而是将新方法直接添加到原始类而不是创建子类:
def better_foo(self):
print('better_foo')
def useful_stuff(cls):
cls.better_foo = better_foo
return cls
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.