Python 中自由变量的搜索顺序是什么?

发布于 2024-09-12 09:01:25 字数 711 浏览 5 评论 0原文

具体来说,自由变量如何在类方法的定义中绑定?它可能是这样的:

  1. 封闭函数(临时)作用域=>生成闭包
  2. 全局(永久)范围=>不生成闭包(只需在方法体执行时查找它)
  3. raise UnboundLocalError()

这里有两个例子:

globalname = 0
class Test(object):
    def method(self):
        print globalname
        print Test

def outer():
    localname = 1
    class Test(object):
        def method(self):
            print globalname
            print localname
            print Test
    return Test

Test().method.__func__.__closure__
# None
outer()().method.__func__.__closure__
# (<cell at 0xb7d655b4: type object at 0x82412bc>, <cell at 0xb7d655cc: int object at 0x81b20b0>)

我找不到太多关于在定义时如何处理它们的具体文档。上述解释正确吗?

Specifically, how are free variables bound at definition for methods of a class? It is probably something like this:

  1. enclosing function (temporary) scope => generate closure
  2. global (permanent) scope => generate no closure (just look it up when the method body executes)
  3. raise UnboundLocalError()

Here are two examples:

globalname = 0
class Test(object):
    def method(self):
        print globalname
        print Test

def outer():
    localname = 1
    class Test(object):
        def method(self):
            print globalname
            print localname
            print Test
    return Test

Test().method.__func__.__closure__
# None
outer()().method.__func__.__closure__
# (<cell at 0xb7d655b4: type object at 0x82412bc>, <cell at 0xb7d655cc: int object at 0x81b20b0>)

I couldn't find much documentation on specifically how they are treated at definition time. Is the above explanation correct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤千羽 2024-09-19 09:01:26

当且仅当一个变量被分配到当前代码块内时,Python 才假定该变量是局部变量。因此,

spam = 0
def ham:
    print( spam )

将使垃圾邮件成为一个全局变量,但

spam = 0
def ham:
    spam = 0
    print( spam )

会成为一个单独的变量,对于ham来说是本地的。闭包获取封闭范围内的所有本地变量。在您的第一个示例中,没有局部变量,因此没有闭包;在第二个中,localname被分配,因此method是一个闭包。

与 Python 中一样,有很多方法可以绕过这个假设。 global 关键字将变量声明为全局(!),因此例如

spam = 0
def ham:
    global spam
    spam = 0
    print( spam )

不是闭包。 Py3k 引入了 nonlocal 关键字,它告诉 Python 向上查找范围,直到找到变量名并引用它。

Python assumes a variable is local if and only if it is assigned to, within the current code block. So

spam = 0
def ham:
    print( spam )

will make spam a global variable, but

spam = 0
def ham:
    spam = 0
    print( spam )

will make a separate variable, local to ham. A closure grabs all the variables local to the enclosing scope. In your first example, there are no local variables so no closure; in the second, localname is assigned to and thus method is a closure.

As always in Python, there are ways around this assumption. The global keyword declares a variable as global (!), so e.g.

spam = 0
def ham:
    global spam
    spam = 0
    print( spam )

will not be a closure. Py3k introduces the nonlocal keyword, which tells Python to look upwards through the scopes until it finds the variable name and refer to that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文