繁体   English   中英

局部变量如何与Python闭包一起使用?

[英]How do local variables work with Python closures?

当我运行以下Python3代码时,

def f():
  x = 'foo'
  def g():
    return x
  def h(y):
    nonlocal x
    x = y
  return g, h
g, h = f()
print(g())
h('bar')
print(g())

我懂了

foo
bar

我相信在Python中,所有局部变量本质上都是指针。 因此,在我看来, x是调用f()时在堆栈上分配的指针,因此当f()退出时,变量x应该消失。 由于字符串'foo'是在堆上分配的,因此当调用g()时,我想“好吧,我想g()也会保留指向'foo'的指针的副本”。 但是然后我可以调用h('bar')g()返回的值得到更新。

变量x存放在哪里? 我在Python中的局部变量模型是否全部错误?

编辑:

@chepner在评论中几乎回答了我的问题。 他说一个地方变量存储在类似dict的对象中,然后他另一个地方链接https://docs.python.org/3.4/reference/executionmodel.html#naming-and-binding来支持他要求。

在这一点上我很高兴。 如果chepner要写一个答案以重新表达他的评论,我会接受它为最佳答案。 否则,认为此问题已解决。

@chepner很久以前在评论中回答了我的问题。

如果他发布一个,我会接受@chepner的回答。 但是已经快一年了,我认为现在就自己发布答案并接受它是公平的。


我最初问这个问题是因为我不理解Python中存储在堆栈框架中的内容。

在Java中,如果您的代码如下所示:

void f() {
  Integer x = 1;
  Integer y = 2;
}

内存在堆栈上分配了两个指针。

但是,在Python中,如果您有类似

def f():
  x = 1
  y = 2

堆栈上没有分配额外的内存。

在伪C ++中,上面的python代码更类似于

void f() {
  PythonDict * scope = MakePythonDict();
  scope->set("x", MakeInt(1));
  scope->set("y", MakeInt(2));
}

因此,对于我最初的问题,变量x保持活动状态,因为它位于scope所指向的dict中,而该scope在闭包中传递。

请注意,当函数退出时, scope指针仍会消失。

暂无
暂无

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

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