Python 马克·卢茨让我有点困惑

Python 马克·卢茨让我有点困惑,python,function,Python,Function,在第一次使用函数时(没有技术编码背景),我无法理解这样的概念 一个简单的函数工厂: 简单地说明这一点,请考虑在交互式提示符下键入的以下函数: >>> def maker(N): ... def action(X): # Make and return action ... return X ** N # action retains N from enclosing scope ... return action 这定义了一个外部函数,它只生成

在第一次使用函数时(没有技术编码背景),我无法理解这样的概念

一个简单的函数工厂:

简单地说明这一点,请考虑在交互式提示符下键入的以下函数:

>>> def maker(N):
...     def action(X): # Make and return action
...         return X ** N # action retains N from enclosing scope
...     return action
这定义了一个外部函数,它只生成并返回一个嵌套函数,而不调用它maker make action,但只返回action而不运行它。如果我们调用外部函数:

>>> f = maker(2) # Pass 2 to argument N
>>> f
>>> f(3) # Pass 3 to X, N remembers 2: 3 ** 2
9
>>> f(4) # 4 ** 2
16
.在0x0000000002A4 A158>

我们得到的是对生成的嵌套函数的引用,该函数是在嵌套def运行时创建的。如果我们现在调用从外部函数得到的结果:

>>> f = maker(2) # Pass 2 to argument N
>>> f
>>> f(3) # Pass 3 to X, N remembers 2: 3 ** 2
9
>>> f(4) # 4 ** 2
16
我们调用嵌套函数,即maker中名为action的函数。换句话说,我们正在调用maker创建并传回的嵌套函数。 也许最不寻常的是,嵌套函数会记住整数2,即maker中变量N的值,即使在调用操作时maker已经返回并退出。实际上,封闭局部作用域中的N作为附加到生成的操作的状态信息保留,这就是为什么我们在稍后调用它时将其参数平方化。同样重要的是,如果我们现在再次调用外部函数,我们会得到一个附加了不同状态信息的新嵌套函数。也就是说,在调用新函数时,我们得到的参数是立方而不是平方,但原始参数仍然是平方:

>>> g = maker(3) # g remembers 3, f remembers 2
>>> g(4) # 4 ** 3
64
>>> f(4) # 4 ** 2 

这里到底发生了什么。请给我一个我能理解的视角

动作
就是我们所说的结束。它是一个函数对象和一个包含所谓自由变量值的环境的组合,自由变量是函数体中使用的非局部名称

在这种情况下,
action
是包含
n
值的环境上的闭包,该值从定义了
action
maker
调用中“继承”。请注意,对
maker
的每次调用都定义了一个名为
action
的新函数对象。调用
maker
返回的闭包包含此新函数和传递给
maker
n


实际上,函数和闭包之间几乎没有区别;它的行为与函数完全相同,只是它的一些非本地名称的值来自其封闭的环境,而不是全局或调用范围。

请尝试改进您问题的标题:目前还不清楚问题的内容。您的描述是正确的,返回的函数将保留这一点点状态。这称为词法闭包,它是一个函数,在创建该函数时,包含词法范围中的变量,这些变量被“关闭”并与函数一起保存。我不确定你的问题最终是什么,但是,你是在问这是如何实现的吗?另请参阅关于修改Closure捕获的变量这显然是我第一次讨论堆栈溢出。我欢迎你的反馈。将随着时间的推移而改善