在装饰器中扩展 class in Python
Extending a class in Python inside a decorator
我正在使用装饰器来扩展某些 classes 并向它们添加一些功能,如下所示:
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')
不幸的是,由于非全局 LocalClass
,MyClass 不再是 pickleable
AttributeError: Can't pickle local object 'useful_stuff.<locals>.LocalClass'
- 我需要腌制我的 classes。你能推荐一个更好的设计吗?
- 考虑到 class 上可以有多个装饰器,通过让 MyClass 继承所有功能来切换到多重继承是否是更好的选择?
您需要设置元数据,使子class看起来像原来的:
def deco(cls):
class SubClass(cls):
...
SubClass.__name__ = cls.__name__
SubClass.__qualname__ = cls.__qualname__
SubClass.__module__ = cls.__module__
return SubClass
类 通过使用他们的模块和 qualname 来 pickled 来记录在哪里可以找到 class。您的 class 需要在与原始 class 相同的位置找到,如果它没有被装饰的话,所以 pickle 需要看到相同的模块和 qualname。这类似于 funcutils.wraps
对修饰函数所做的。
但是,将新方法直接添加到原始 class 而不是创建子方法可能会更简单且更不容易出错 class:
def better_foo(self):
print('better_foo')
def useful_stuff(cls):
cls.better_foo = better_foo
return cls
我正在使用装饰器来扩展某些 classes 并向它们添加一些功能,如下所示:
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')
不幸的是,由于非全局 LocalClass
,MyClass 不再是 pickleableAttributeError: Can't pickle local object 'useful_stuff.<locals>.LocalClass'
- 我需要腌制我的 classes。你能推荐一个更好的设计吗?
- 考虑到 class 上可以有多个装饰器,通过让 MyClass 继承所有功能来切换到多重继承是否是更好的选择?
您需要设置元数据,使子class看起来像原来的:
def deco(cls):
class SubClass(cls):
...
SubClass.__name__ = cls.__name__
SubClass.__qualname__ = cls.__qualname__
SubClass.__module__ = cls.__module__
return SubClass
类 通过使用他们的模块和 qualname 来 pickled 来记录在哪里可以找到 class。您的 class 需要在与原始 class 相同的位置找到,如果它没有被装饰的话,所以 pickle 需要看到相同的模块和 qualname。这类似于 funcutils.wraps
对修饰函数所做的。
但是,将新方法直接添加到原始 class 而不是创建子方法可能会更简单且更不容易出错 class:
def better_foo(self):
print('better_foo')
def useful_stuff(cls):
cls.better_foo = better_foo
return cls