python类装饰器不起作用

时间:2016-12-08 05:13:57

标签: python

import time
class Timeit(object):
    def __init__(self, func):
        self._wrapped = func
    def __call__(self, *args, **kws):
        start_time = time.time()
        result = self._wrapped(*args, **kws)
        print("elapsed time is %s " % (time.time() - start_time))
        return result

我写这样的类装饰器,然而,当我将它用于实例方法时,它不起作用。

class A(object):
    @Timeit
    def func(self):
        time.sleep(1)
        return 'invoking method func'
 if __name__ == '__main__':
    a = A()
    a.func()  # Boom!

任何人都可以解释我为什么?它在常规方法中效果很好。

1 个答案:

答案 0 :(得分:0)

问题是你的@Timeit装饰器意味着A.func是一个对象,而不是一个函数。因此,当您评估:

a.func()

使用隐式self参数将函数转换为绑定方法的类方法的特殊Python处理不会生效。如果你要跑:

a.func(a)

提供缺失的论点,它会工作正常,但显然这不是你想要的。

您需要确保包装器返回一个函数,而不是一个对象。最简单的方法是放弃将Timeit作为一个类实现,并将代码替换为:

import time
from functools import wraps

def Timeit(f):
    @wraps(f)
    def wrapper(*args, **kwds):
        start_time = time.time()
        result = f(*args, **kwds)
        print("elapsed time is %s " % (time.time() - start_time))
        return result
    return wrapper

class A(object):
    @Timeit
    def func(self):
        time.sleep(1)
        return 'invoking method func'

if __name__ == '__main__':
    a = A()
    a.func()  # works fine now