我在理解带有装饰器的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 callablehttps://stackoverflow.com/questions/52247498
复制相似问题