提议的类装饰器实现与函数实现略有不同:它将无法在方法上运行。
class Decorator(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print('something')
self.func(*args, **kwargs)
class A:
@Decorator
def mymethod(self):
print("method")
A().mymethod()
将会引发 TypeError: mymethod() 缺少 1 个必需的位置参数: 'self'
要添加方法支持,您需要实现 __get__
import types
class Decorator2(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print('something')
self.func(*args, **kwargs)
def __get__(self, instance, owner):
if instance is None:
return self
return types.MethodType(self, instance)
class B:
@Decorator2
def mymethod(self):
print("method")
B().mymethod()
将输出
class B:...
something
method
这段代码之所以能够运行,是因为当你访问
B().mymethod
时,首先调用了
__get__
并提供绑定的方法。然后再调用
__call__
。
总之,只要定义了
__get__
,类和函数实现就可以以相同的方式使用。有关更多信息,请参见 Python Cookbook 中的第 9.9 节。