局部变量如何与Python闭包一起使用? [英] How do local variables work with Python closures?

查看:45
本文介绍了局部变量如何与Python闭包一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我运行以下Python3代码时,

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())

我知道

foo
bar

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

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.

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

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

@chepner在评论中几乎回答了我的问题.他在其中一个地方说局部变量存储在类似dict的对象中,然后在另一个地方他链接

@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.

在这一点上我很高兴.如果chepner要写一个答案以重新表达他的评论,我会认为它是最好的答案.否则,请考虑解决此问题.

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.

推荐答案

@chepner早在评论中回答了我的问题.

@chepner answered my question ages ago in the comments.

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

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.

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

I asked the question originally, because I didn't understand what was stored in the stack frame in Python.

在Java中,如果您的代码类似于:

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.

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

However, in Python, if you have code like

def f():
  x = 1
  y = 2

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

No extra memory is allocated on the stack.

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

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));
}

因此,对于我最初的问题,变量 x 仍然有效,因为它存在于 scope 指向的字典中,并在闭包中传递.

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.

请注意,当函数退出时, scope 指针仍然会死.

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

这篇关于局部变量如何与Python闭包一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆