我对Python装饰器有疑问。
class decorator(object):
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
print('sth to log: %s : %s' % (self.function.__name__, args))
return self.function(*args, **kwargs)
@decorator
def sum_test(a, b):
print('sum: %s' % (a+b))
@decorator
class Class_test(object):
def __init__(self):
pass
def sum_func(self, a, b):
print('class sum: %s' % (a+b))
return a+b
if __name__ == '__main__':
sum_test(3, 4)
func = Class_test()
var1 = func.sum_func(1, 4)
print(var1)
输出:
sth to log: sum_test : (3, 4)
sum: 7
sth to log: Class_test : ()
class sum: 5
5
装饰器正在按我想要的功能sum_test
工作。我可以记录函数sum_test
与变量3
和4
一起使用。
我在装饰类时遇到问题。我可以记录创建类Class_test
的对象,但是我没有使用功能sum_func
的信息。
为什么在类对象上运行__call__()
时装饰器中的sum_func
没有被触发,而直接在函数sum_test
中使用时为什么被触发?
答案 0 :(得分:0)
使用decorator
装饰类意味着Class_test
现在是decorator
对象,因此Class_test.function
是您为其编写主体的类。
请记住,@decorator
语法是
class Class_test(object):
def __init__(self):
pass
def sum_func(self, a, b):
print('class sum: %s' % (a+b))
return a+b
Class_test = decorator(Class_test)
(除非Class_test
符号从来没有指向您的班级)。
因此,在您调用decorator
时会调用此Class_test
对象,这恰好是您在日志中看到的:
sth to log: Class_test : ()
另一方面, func.sum_func
是常规绑定方法。它对decorator
一无所知。
如果要在类中使用它,我更喜欢使用封闭式装饰器(返回函数的函数)。它返回的函数通常将由class
机制注册为一个方法。
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('sth to log: %s : %s' % (func.__name__, args))
return func(*args, **kwargs)
return wrapper
class Class_test(object):
@decorator
def sum_func(self, a, b):
print('class sum: %s' % (a+b))
return a+b
如果您仍然想使用基于类的方法,请阅读Python Class Based Decorator with parameters that can decorate a method or a function