简体   繁体   English

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

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

When I run the following Python3 code, 当我运行以下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())

I get 我懂了

foo
bar

I had believed that in Python, all local variables are essentially pointers. 我相信在Python中,所有局部变量本质上都是指针。 So in my mind, x was a pointer allocated on the stack when f() is called, so when f() exits, the variable x should die. 因此,在我看来, x是调用f()时在堆栈上分配的指针,因此当f()退出时,变量x应该消失。 Since the string 'foo' was allocated on the heap, when g() is called, I thought "ok, I guess g() kept a copy of the pointer to 'foo' as well". 由于字符串'foo'是在堆上分配的,因此当调用g()时,我想“好吧,我想g()也会保留指向'foo'的指针的副本”。 But then I could call h('bar') , the value that g() returns got updated. 但是然后我可以调用h('bar')g()返回的值得到更新。

Where does the variable x live? 变量x存放在哪里? Is my model of local variables in Python all wrong? 我在Python中的局部变量模型是否全部错误?

EDIT: 编辑:

@chepner has pretty much answered my question in the comments. @chepner在评论中几乎回答了我的问题。 There's one where he says that local variables are stored in a dict-like object, and then another where he links https://docs.python.org/3.4/reference/executionmodel.html#naming-and-binding , to support his claim. 他说一个地方变量存储在类似dict的对象中,然后他另一个地方链接https://docs.python.org/3.4/reference/executionmodel.html#naming-and-binding来支持他要求。

At this point I am pretty happy. 在这一点上我很高兴。 If chepner were to write an answer rehashing his comments I would accept it as best answer. 如果chepner要写一个答案以重新表达他的评论,我会接受它为最佳答案。 Otherwise, consider this question resolved. 否则,认为此问题已解决。

@chepner answered my question ages ago in the comments. @chepner很久以前在评论中回答了我的问题。

I would've accepted @chepner's answer if he posted one. 如果他发布一个,我会接受@chepner的回答。 But it's been almost a year, and I think it's fair for me to just post the answer myself now, and accept it. 但是已经快一年了,我认为现在就自己发布答案并接受它是公平的。


I asked the question originally, because I didn't understand what was stored in the stack frame in Python. 我最初问这个问题是因为我不理解Python中存储在堆栈框架中的内容。

In Java, if you have code that looks like: 在Java中,如果您的代码如下所示:

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

Memory is allocated on the stack for two pointers. 内存在堆栈上分配了两个指针。

However, in Python, if you have code like 但是,在Python中,如果您有类似

def f():
  x = 1
  y = 2

No extra memory is allocated on the stack. 堆栈上没有分配额外的内存。

In pseudo-C++, the python code above is more analogous to 在伪C ++中,上面的python代码更类似于

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

So for my original question, the variable x stays alive because it lives in the dict pointed to by scope which gets passed around in the closure. 因此,对于我最初的问题,变量x保持活动状态,因为它位于scope所指向的dict中,而该scope在闭包中传递。

Notice that the scope pointer still dies when the function exits. 请注意,当函数退出时, scope指针仍会消失。

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

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