Python装饰器15-开始使用类作为装饰器
2019-06-15 本文已影响0人
dnsir
基于前面的使用函数作为装饰器的理解,将类作为装饰器时需要保证以下几点
- 类的实例是可调用的
- 类需要一个地方讲被装饰的函数传入到类的实例里
第一条可以通过__call__
实现,第二条可以通过__init__
实现。
手工将类作为装饰器使用
class Profiled:
def __init__(self, func):
# wraps(func)(self)
self.func = func
def __call__(self, *args, **kwargs):
print("call")
return self.func(*args, **kwargs)
def add(x, y):
return x + y
add = Profiled(add)
result = add(1, 2)
print(result)
执行结果:
call
3
似乎再用语法糖包装一下就可以实现将类作为装饰器来使用了。
使用类作为装饰器使用
from functools import wraps
class Profiled:
def __init__(self, func):
# wraps(func)(self)
self.func = func
def __call__(self, *args, **kwargs):
print("call")
return self.func(*args, **kwargs)
@Profiled
def add(x, y):
return x + y
result = add(1, 2)
print(result)
运行结果同上。
小结
这节我们以我们理解的方法实现了将类作为装饰器使用,看起来都很正确,似乎就是这样使用?但是这种方法还有一些别的问题,最重要的是同样的问题,可以在代码中使用:
print(add.__name__)
发现无法输出__name__
,根据约定使用装饰器不能改变函数的__name__
属性,因此我们还需要改进将类作为装饰器的使用方法。