1

我对 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与变量34.

我对装饰课程有疑问。我可以记录该类对象Class_test已创建,但我没有使用该函数sum_func的信息。

为什么在类对象上__call__()运行时没有触发装饰器,而sum_func直接在函数上使用时会触发sum_test

4

1 回答 1

0

用现在是一个对象的decorator方式装饰类,这就是您为其编写主体的类。Class_testdecoratorClass_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 decoration a method or a function

于 2019-01-08T21:27:11.663 回答