第一次执行功能(没有技术编码背景)我无法理解一个概念,就是这样。
一个简单的功能工厂:
为了简单地说明这一点,请考虑在交互式提示符下输入的以下函数:
>>> def maker(N):
... def action(X): # Make and return action
... return X ** N # action retains N from enclosing scope
... return action
这定义了一个外部函数,它只是简单地生成并返回一个嵌套函数,而不需要调用它来制作动作,而只是在不运行它的情况下返回动作。如果我们调用外部函数:
>>> f = maker(2) # Pass 2 to argument N
>>> f
.action at 0x0000000002A4A158>
我们得到的是对生成的嵌套函数的引用 - 嵌套def运行时创建的嵌套函数。如果我们现在调用从外部函数返回的内容:
>>> f(3) # Pass 3 to X, N remembers 2: 3 ** 2
9
>>> f(4) # 4 ** 2
16
我们调用嵌套函数 - 在maker中调用action的函数。换句话说,我们正在调用创建者创建并传回的嵌套函数。 但是,也许最不寻常的部分是嵌套函数记住整数2,即制造商中变量N的值,即使制造商已经返回并在我们调用该操作时退出。实际上,封闭的局部作用域中的N被保留为附加到生成的动作的状态信息,这就是为什么我们在稍后调用它时返回其参数的平方。同样重要的是,如果我们现在再次调用外部函数,我们将返回一个附加了不同状态信息的新嵌套函数。也就是说,当调用新函数时,我们得到参数cubed而不是平方,但原始仍然像以前一样正方形:
>>> g = maker(3) # g remembers 3, f remembers 2
>>> g(4) # 4 ** 3
64
>>> f(4) # 4 ** 2
这里究竟发生了什么。请给我一个我能理解的观点。
答案 0 :(得分:1)
action
就是我们所说的闭包。它是一个函数对象的组合,以及一个包含所谓的 free 变量值的环境,这些变量是函数体中使用的非本地名称。
在这种情况下,action
是对包含n
值的环境的闭包,该值为"继承"从定义maker
的{{1}}调用开始。请注意,每次调用action
都会定义一个名为maker
的 new 函数对象。通过调用action
返回的闭包由此新函数和传递给maker
的{{1}}的值组成。
实际上,函数和闭包之间几乎没有区别;它的行为与函数完全相同,只是它的一些非本地名称从其封闭的环境而不是全局或调用范围中获取它们的值。