任何人都可以解释这一点我知道装饰器的功能,但仍然没有得到输出

时间:2018-03-30 06:13:49

标签: python python-3.x

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 我知道装饰器的功能,但我仍然没有得到输出。

2 个答案:

答案 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三次。由于innerfnc是相同的,inner.cofnc.co是相同的。所以print(fnc.co)打印3。

答案 1 :(得分:0)

在python中,函数是“第一类对象”(参见What are "first class" objects?)。这意味着您可以在它们上设置属性。您可以在此处定义函数fnc,并且装饰器c会向该函数对象fnc.co添加属性。在声明包装函数之后完成inner.co = 0初始化有点奇怪,但是由于inner在定义co属性之后才会被调用,因此无关紧要。然后在inner中,co属性在每次调用函数时都会递增。