Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么我的decorator按这种顺序执行代码?_Python_Python 3.x_Decorator - Fatal编程技术网

Python 为什么我的decorator按这种顺序执行代码?

Python 为什么我的decorator按这种顺序执行代码?,python,python-3.x,decorator,Python,Python 3.x,Decorator,我有下面的代码,我很难理解为什么它会按顺序打印语句 def main(): print('1') registry=[] def register(func): print('2') registry.append(func) return func @register def f1(): print('3') print('4') f1() main() 此代码打印: 1 2 4 3 但我想知道为什么它不打印: 1 2 3 4 调用@寄

我有下面的代码,我很难理解为什么它会按顺序打印语句

def main():
    print('1')
    registry=[]

def register(func):
    print('2')
    registry.append(func)
    return func

@register
def f1():
    print('3')
print('4')
f1()
main()
此代码打印:

1
2
4
3
但我想知道为什么它不打印:

1
2
3
4

调用
@寄存器
时,我知道调用了
寄存器(f1)
,它会打印
2
,然后返回
f1
。在我看来,由于返回了
f1
,接下来应该打印
3
。但是,直到语句的最后,
f1()
才调用
f1
return func
是否运行它返回的函数?

考虑不使用decorator语法的等效代码。此外,我们将
注册表
设置为预定义的全局注册表,以便代码实际运行

registry = []

def main():
    print('1')
    #registry=[]

def register(func):
    print('2')
    registry.append(func)
    return func

def f1():
    print('3')

f1 = register(f1)
print('4')
f1()
main()
调用的第一个函数是
寄存器
,因此第一个值输出是
2
。接下来,
print('4')
输出
4
。第三,调用
f1
,并输出
3
。最后,调用
main
,并输出
1


register
从不调用
f1
;它只是简单地将它添加到列表
注册表中并返回它。

代码不会运行,因为
注册表
main()
函数的本地函数,并且在
register
decorator中没有定义。在我看来,由于返回了f1,接下来应该打印3个代码,但刚刚返回了
f1
;它不叫。(但实际上,对我来说,它打印的是
2 4 3 1
)即使
registry
是一个预定义的全局值,第一个值输出也是2,因为
register
main
之前运行。那么如果它不运行/调用函数,return func语句用于什么呢?它返回
函数
对象本身(这样就可以将它重新分配给原始名称);请参见
f1=register(f1)
。实际上,装饰器语法不允许你做没有它就做不到的事情;这纯粹是一种方便。基本上,像这样使用
@register
可以避免你编写
registry.append(f1)
在定义
f1
之后。但是通过使用修饰符,您必须确保名称
f1
实际上是指定义的函数,这就是为什么
register
也必须返回
f1
的原因。