为什么每次装饰函数时都会触发装饰器,而不是在调用装饰函数时触发?

问题描述 投票:0回答:2

在下面的代码中,为什么每次我们装饰函数时(例如,当我们装饰函数

ls1
时)都会更新
api4
,而不是每次调用特定函数时都更新?

ls1=[]

def register_usage(f):
    ls1.append((datetime.today(), f.__name__))
    return f

@register_usage
def api4():
    return 'api4'
python python-decorators
2个回答
3
投票

因为这就是装饰器的工作原理。

当你写下:

@register_usage
def api4():
  ...

这完全等同于:

def orig_api4():
  pass

api4 = register_usage(orig_api4)

也就是说,装饰器接收装饰函数作为参数并返回一个新函数,从那时起,该新函数将替换原始函数。这一切都发生在函数定义时。

当您调用装饰函数时,您只是调用装饰器返回的任何函数。


0
投票

要创建一个在每次调用函数时都执行一些工作的装饰器,您需要创建并返回一个内部函数。

ls1=[]

def register_usage(f):
    def impl():
        ls1.append((datetime.today(), f.__name__))
        return f()
    return impl

@register_usage
def api4():
    return 'api4'

现在

api4()
实际上会调用
impl()
,它会附加到您的全局列表,然后委托给 original
api4

© www.soinside.com 2019 - 2024. All rights reserved.