我在理解带有装饰器的Python程序中的控制流方面有困难。
def executor(func):
def innerExecutor():
#print("inside executor")
print("------------------------")
func()
print("------------------------")
return innerExecutor
@executor
def multiply():
n1 = 10
n2 = 20
print("multiplication = ", (n1 * n2))
multiply()
我遇到的问题是:当调用executor()
函数并返回innerExecutor()
的引用时,这个引用存储在哪里?控件何时实际传递给内部函数?我是Python的新手。
发布于 2018-09-09 19:21:23
语法
@some_decorator
def somefunc():
...
相当于:
somefunc = some_decorator(somefunc)
这在Python中是可能的,因为函数是一流对象。它们可以作为参数传递给其他函数,并从其他函数返回--即所谓的高阶函数。
在您的示例中,对multiply()
的最后调用实际上运行了innerExector()
,这是一个由multiply()
修饰定义创建的函数。要了解这里发生的事情,请仔细查看executor
的定义
def executor(func):
def innerExecutor():
#print("inside executor")
print("------------------------")
func()
print("------------------------")
return innerExecutor
当守则:
@executor
def multiply():
...
运行时,将以函数executor
作为参数调用函数multiply
。executor
定义函数innerExecutor()
,并返回它,但不执行它。innerExecutor()
的这个实例被调用来代替将来对multiply()
的所有引用。
但是等等--通常,我们不想完全替换正在修饰的函数。innerExecutor()
需要在某个时候调用修饰函数。回想一下,修饰函数定义:
@executor
def multiply():
...
相当于:
def multiply():
...
multiply = executor(multiply)
将要修饰的函数作为参数传递给装饰器,允许innerExecutor()
的定义调用它。但是,等待- innerExecutor()
是在executor()
返回并且它的参数func
已经超出范围之后才被调用的。那它为什么起作用呢?
由于Python的另一个特性叫做闭锁。这意味着内部函数可以引用在封闭作用域中定义的局部变量--包括传递到外部函数executor
的参数--即使在退出封闭作用域之后也是如此。闭包的神奇之处在于,解释器检测内部函数定义对外部函数的局部变量的依赖,即使在executor()
返回之后也保持它可用。这个链接更详细地介绍了闭包。
最后,最后一行中对multiply()
的调用实际上调用了在运行修饰定义时创建的innerExecutor()
实例,而后者又调用了multiply()
的原始未修饰版本。
每次装饰器用于装饰函数定义时,它都会创建内部函数的一个新实例,该实例将替换未修饰的函数。因此,如果装饰5个不同的函数,就会创建5个不同的innerExecutor()
实例。稍后,当调用任何这些修饰函数时,它将转而调用适当的innerExecutor()
实例,后者反过来调用相应的未修饰函数。
发布于 2018-09-09 19:46:16
它返回innerExecutor()的引用,该引用存储在哪里? 控件何时实际传递给内部函数?
它不是存储在任何地方,它的名称如下:
innerExecutor(multiply)
这就是为什么您的装饰方法需要返回它自己的引用,否则,它将等价于以下内容:
None(multiply) # TypeError: 'NoneType' object is not callable
https://stackoverflow.com/questions/52247498
复制相似问题