def c(f):
def inner(*args, **kargs):
inner.co += 1
return f(*args, **kargs)
inner.co = 0
return inner
@c
def fnc():
pass
if __name__ == '__main__':
fnc()
fnc()
fnc()
print(fnc.co)
请解释最终输出:3
我知道装饰器的功能,但我仍然没有得到输出。
答案 0 :(得分:4)
首先,让我们解压缩装饰器语法的作用。当你这样写:
@c
def fnc():
pass
......它等同于:
def fnc():
pass
fnc = c(fnc)
现在看看c
做了什么:它创建了一个名为inner
的新函数,并将inner.co
设置为0,并返回inner
代替fnc
。所以,现在你的代码等同于:
def fnc():
pass
def inner(*args, **kargs):
inner.co += 1
return fnc(*args, **kargs)
inner.co = 0
fnc = inner
因此,当您拨打fnc()
三次时,您每次都会调用inner
。所以它增加inner.co
三次。由于inner
和fnc
是相同的,inner.co
和fnc.co
是相同的。所以print(fnc.co)
打印3。
答案 1 :(得分:0)
在python中,函数是“第一类对象”(参见What are "first class" objects?)。这意味着您可以在它们上设置属性。您可以在此处定义函数fnc
,并且装饰器c
会向该函数对象fnc.co
添加属性。在声明包装函数之后完成inner.co = 0
初始化有点奇怪,但是由于inner
在定义co
属性之后才会被调用,因此无关紧要。然后在inner
中,co
属性在每次调用函数时都会递增。