当我运行以下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'
的指针的副本以及#34;。但是我可以调用h('bar')
,g()
返回的值得到更新。
变量x
在哪里生活?我在Python中的局部变量模型是否都错了?
编辑:
@chepner在评论中几乎回答了我的问题。在那里,他说局部变量存储在类似dict的对象中,然后是另一个链接https://docs.python.org/3.4/reference/executionmodel.html#naming-and-binding,以支持他的主张。
此时我很开心。如果chepner要写一个回答他的评论,我会接受它作为最佳答案。否则,请考虑解决此问题。
答案 0 :(得分:0)
@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
指针仍然会死。