简体   繁体   English

高阶函数中的闭包魔术。

[英]Closure magic in higher-order functions.

It's easy to know how to assign a global variable to an inner function - which would make the global variable a function itself thats equal to the inner function - but how does the interpreter know how to call an argument from the inner function by using the code below? 很容易知道如何向内部函数分配全局变量-这将使全局变量成为与内部函数相等的函数本身-但是解释器如何知道如何通过使用代码从内部函数调用自变量下面?

def outer(arg):
    def inner(arg2):
        print(arg, ',', arg2):
    return inner

a = outer(‘outer arg’)

print(a) # .inner at 0x109bd0048
a('inner arg') # Output: outer arg, inner arg

Doing print(a) , we see the variable/function a becomes the inner function. 进行print(a) ,我们看到变量/函数a成为内部函数。

What I don't understand, is how assigning the a variable to the outer function targets the inner function and argument with the code, a('inner argument')) 我不明白的是,如何将a变量分配给外部函数,并使用代码a('inner argument'))将内部函数和参数作为目标

Is it somehow implicitly calling the inner function without explicitly stating it? 是否以某种方式隐式调用内部函数而不显式声明它?

Is it doing something like this: 它正在做这样的事情:

a = outer('outer arg')inner('inner arg')

Where is the python source code behind this magic? 魔术背后的python源代码在哪里?

I don't have enough reputation for a comment, so I have to write an answer... 我没有足够的声誉来发表评论,所以我必须写一个答案...

From the excellent "Fluent Python" by Luciano Ramalho: 摘自Luciano Ramalho出色的“ Fluent Python”:

"...Python keeps the names of local and free variables in the __code__ attribute that represents the compiled body of the function" “ ... Python将本地和自由变量的名称保留在表示该函数已编译主体的__code__属性中”

"To summarize: a closure is a function that retains the bindings of the free variables that exist when the function is defined, so that they can be used later when the function is invoked and the defining scope is no longer available" “总结:闭包是一个函数,它保留定义函数时存在的自由变量的绑定,以便以后在调用该函数且定义范围不再可用时可以使用它们”

I added a couple of rows to your code to visualize this: 我在您的代码中添加了几行来可视化此代码:

def outer(arg):
    def inner(arg2):
        print(arg, ',', arg2)
    print (inner.__code__.co_freevars)
    print (inner.__closure__[0].cell_contents)
    return inner

Which prints the following: 打印以下内容:

In [169]: outer('outer arg')
('arg',)
outer arg

So as you can see the value of arg is preserved even after the function has gone out of scope, since it is a free variable. 因此,您可以看到,即使函数超出范围,arg的值仍会保留,因为它是一个自由变量。 The binding for arg is kept in the __closure__ attribute. arg的绑定保留在__closure__属性中。

This is only a hint for further reading, I am by no means an expert. 这只是进一步阅读的提示,我绝不是专家。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM