提问人:master_latch 提问时间:3/11/2023 更新时间:3/11/2023 访问量:68
在 Python 中,函数是否捕获定义函数后创建的变量?
In Python, does a function capture variables created after the function is defined?
问:
我试图更好地理解闭包。根据我的理解,示例 1 - 3 对我来说是有意义的,但我认为它一定是不正确的,因为示例 4 对我来说没有意义。
示例 1
def f():
print(x)
x=1
f() # prints 1
当时定义,不存在,但没关系。它将在被调用时被查找,此时存在。f()
x
f()
x
示例 2
y=2
def g():
print(y)
g() # prints 2
这是一个结束。何时定义、存在并捕获对它的引用。如果我要更改 after defined 的值,则在调用时将反映此更改。据我所知,这不涉及关闭。g()
y
g()
y
g()
g()
示例 3
def h():
x=3
def i():
print(x)
return i
j=h()
j() # prints 3
这仅表明,即使在变量超出范围后,闭包仍保留对变量的引用。一旦返回,我就不能直接引用,因为它已经超出了范围,但保留了对它的引用。h()
x
j()
示例 4
def k():
def l():
print(x)
x=4
return l
m=k()
m() # prints 4
这让我感到困惑。我认为(正如我在示例 1 中声称的那样)这不是一个闭包,因此它不保留对 ;它只是在调用时尝试查找。但是,事实上,当我们通过 调用它时,即使它已经超出了范围,也会被打印出来。这是否意味着示例 1 中也是一个闭包?令人惊讶的是,一个函数可以捕获在其定义后创建的变量。除非说它捕获变量本身是错误的。说它捕获了定义它的“环境”或“范围”是否更准确?l()
x
x
m()
x
f()
答:
1赞
rv.kvetch
3/11/2023
#1
根据问题:
def k():
def l():
print(x)
x=4
return l
m=k()
m() # prints 4
嵌套函数可以访问外部函数局部变量。在本例中,是函数的局部变量。因此,内部功能也可以访问相同的信息。x=4
k()
l()
进一步研究:我建议启动 REPL 并在终端窗口中尝试一下。python
>>> def k():
... a = 1
... def l():
... print(a, b)
... print(locals())
... b = 2
... print(locals())
... return l
...
>>> k()
{'l': <function k.<locals>.l at 0x10140bec0>, 'a': 1, 'b': 2}
<function k.<locals>.l at 0x10140bec0>
>>> k()()
{'l': <function k.<locals>.l at 0x101414180>, 'a': 1, 'b': 2}
1 2
{'a': 1, 'b': 2}
希望这会有所帮助。
评论
0赞
master_latch
3/11/2023
嵌套函数可以访问外部函数的局部变量这一事实并不是让我感到困惑的部分(这只是一个直接的闭包,如我的示例 3 所示)。让我感到困惑的是,它甚至可以访问在定义内部函数之后定义的变量。但是 OP 上的一条评论中链接的 mCoding 视频清楚地解释了这一点。
0赞
rv.kvetch
3/11/2023
@master_latch我不确定我是否理解混乱在哪里。在哪个点定义函数(在变量之前或之后)定义函数并不重要。真正重要的是在什么范围(级别)上,在它被调用的时候,它可以访问这些变量(如果你考虑一下,这是有道理的)。
评论
mCoding