How do local variables work with Python closures?

北战南征 提交于 2021-02-19 07:25:49

问题


When I run the following Python3 code,

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. 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. 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". But then I could call h('bar'), the value that g() returns got updated.

Where does the variable x live? Is my model of local variables in Python all wrong?

EDIT:

@chepner has pretty much answered my question in the comments. 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.

At this point I am pretty happy. If chepner were to write an answer rehashing his comments I would accept it as best answer. Otherwise, consider this question resolved.


回答1:


@chepner answered my question ages ago in the comments.

I would've accepted @chepner's answer if he posted one. 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.

In Java, if you have code that looks like:

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

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

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.

Notice that the scope pointer still dies when the function exits.



来源:https://stackoverflow.com/questions/25023076/how-do-local-variables-work-with-python-closures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!