如何调用其他类的装饰器(实例方法)?

Tar*_*n K 1 python decorator python-3.x

我有一个名为 的类RMath(),它有 2 个值a和b。然后有一个名为 的函数对这些和add()求和。现在我想记录计算时间。我决定在这里使用装饰器而不触及原来的功能。同时,我不想在同一个类中编写这个装饰器,所以我创建了一个新类 as ,并创建了一个实例方法 as 。但是当我尝试使用这个装饰器时,它会抛出一个错误abHandlertimeit@Handler.timeitTypeError: timeit() missing 1 required positional argument: 'func'

import time

class Handlers():

    def timeit(self, func):
        def timefunc():
            start = time.time()
            func()
            end = time.time()
            print('Time taken: ', end - start)
        return timefunc()

class RMath():
    def __init__(self, a, b):
        self.a = a
        self.b = b

    @Handlers.timeit
    def add(self):
        try:
            self.a + self.b
        except Exception as e:
            return e

a = 10
b = 20
m = RMath(a, b)
c = m.add()
print(c)
Run Code Online (Sandbox Code Playgroud)

至少从错误中我可以看出存在一些问题@Handlers.timeit

有人可以帮我理解这个问题吗?

即使我从装饰器中删除 self,因为def timeit(func):它会抛出错误:TypeError: add() missing 1 required positional argument: 'self'

rv.*_*tch 5

在这种情况下,您可以使用@classmethod或@staticmethod。我的处理方法如下:

from functools import wraps
from time import time


class Handlers:

    @staticmethod
    def timeit(func):

        @wraps(func)
        def timed_func(*args, **kwargs):
            start = time()
            ret = func(*args, **kwargs)
            end = time()
            print(f'[{func.__qualname__}] Time taken: {end - start}')

            return ret

        return timed_func


class RMath:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    @Handlers.timeit
    def add(self):
        try:
            # add a `return` here!
            return self.a + self.b
        except Exception as e:
            return e


a = 10
b = 20
m = RMath(a, b)
c = m.add()
print(c)
Run Code Online (Sandbox Code Playgroud)

出去:

[RMath.add] Time taken: 3.0994415283203125e-06
30
Run Code Online (Sandbox Code Playgroud)

更新:这*args, **kwargs*是处理带有任意数量参数的函数的通用方法,但是如果您明确只是想支持该RMath.add()方法 - 带有单个参数的函数self- 您可以使用稍微不同的方法,如下所示:

[RMath.add] Time taken: 3.0994415283203125e-06
30
Run Code Online (Sandbox Code Playgroud)