【问题标题】:Decorator missing input argument装饰器缺少输入参数
【发布时间】:2022-06-28 23:22:35
【问题描述】:

运行以下代码时:

import time

def ATimer(func,name='AClassFunction'):
    def wrapper(*args,**kwargs):
        start = time.perf_counter()
        output = func(*args,**kwargs)
        args[0].timers[name] = time.perf_counter()-start
        return output
    return wrapper


class AClass():
    def __init__(self):
        self.timers ={}


    @ATimer(name='stuff')
    def stuff(self):
        j=0
        for i in range(100):
            j = j/2 + i
            print(f'j is {j}')

    @ATimer(name='morestuff')
    def morestuff(self):
        j=0
        for i in range(100):
            j = j + i
            print(f'j is {j}')


AnInstance = AClass()

AnInstance.stuff()
AnInstance.stuff()
AnInstance.morestuff()
print(AnInstance.timers)

我得到 TypeError: ATimer() missing 1 required positional argument: 'func' on line 12.

但是鉴于 ATimer 是一个装饰器,它不应该只将stuffmorestuff 作为输入吗?

【问题讨论】:

  • @ATimer(name) 需要返回一个接受函数作为参数的函数。

标签: python python-decorators


【解决方案1】:

当您有一个接受参数的装饰器(在本例中为name)时,您需要牢记逻辑。例如,

@some_decorator
def func():
    ...

相同
def func():
    ...

func = some_decorator(func)

所以,当你有

@ATimer(name='stuff')
def stuff(self):
    ...

和这个一样

def stuff(self):
    ...

stuff = ATimer(name='stuff')(stuff)

Python 之所以抱怨是因为 ATimer,正如您所定义的,它接受两个参数(funcname),但您只传递了一个参数。此外,请注意 ATimer 在这种情况下应该返回 decorator 而不是 decorated 函数,因为 stuff 不是用ATimer 而是用ATimer(name='stuff') 装饰的。

你能做的是

def ATimer(name='AClassFunction'):
    def decorator(func):
        def wrapper(*args,**kwargs):
            start = time.perf_counter()
            output = func(*args,**kwargs)
            args[0].timers[name] = time.perf_counter()-start
            return output
        return wrapper
    return decorator

【讨论】:

    猜你喜欢
    • 2021-02-22
    • 1970-01-01
    • 2020-09-28
    • 2019-11-26
    • 2023-04-03
    • 2019-09-07
    • 2019-01-24
    • 2022-01-22
    • 2020-09-20
    相关资源
    最近更新 更多