问题
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