为什么在全局范围而不是封闭范围中查找未初始化的类变量? [英] Why is an uninitialized class variable looked up in the global scope and not the enclosing scope?

查看:64
本文介绍了为什么在全局范围而不是封闭范围中查找未初始化的类变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这不是我进行编码项目所需的问题,但是我的一个朋友将其发送给了我.问题是:这里打印出了什么?为什么?

  x = 0y = 0def f():x = 1y = 1A类:打印(x,y)x = 2F() 

输出:

  0 1 

我的第一个直觉告诉我应该是"11",但是我错了.我弄弄了代码,发现如果我删除了"x = 2",我会是正确的.但是为什么呢?

此外,当我将变量设置为全局变量时,它也起作用.像这样:

  x = 0y = 0def f():全局x全局yx = 1y = 1A类:打印(x,y)x = 2F() 

输出:

  1 1 

我不是在寻找解决该问题的其他方法,只是为了更好地了解这里发生的事情.

预先感谢

解决方案

此2014年来自KMOD'S BLOG 的博客帖子,最近被由Guido van Rossum发帖.

有人问为什么,圭多回答了:

与Python 2.1向后兼容.

现在我们知道了...

this is not a problem I need for a coding project, but a friend of mine sent this to me. The question is: what gets printed out here? and why?

x = 0
y = 0
def f():
    x = 1
    y = 1
    class A:
        print(x,y)
        x = 2
f()

Output:

0 1

my first instinct told me that it should be "1 1", but I was wrong. I fiddled with the code and found out that if I remove the "x = 2" I would have been correct. but why?

also, it worked when I made the variables global. like this:

x = 0
y = 0
def f():
    global x
    global y
    x = 1
    y = 1
    class A:
        print(x,y)
        x = 2
f()

Output:

1 1

I am not looking for other solutions to the problem, just a better understanding of what is going on here.

thanks in advance

解决方案

This is documented in the last paragraph of Resolution of names:

Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. (emphasis mine)

So, y is looked up, as expected, in the nearest enclosing scope that defines it (the f function, where it gets the value 1).

On the other end, x = 2 causes x to be considered local, and as it isn't already defined in print(x,y), the exception causes it to be looked up in the global namespace (where it gets the value 0), instead of causing a NameError, as would be expected for an unbound local variable in a normal function.


I have long wondered why this special rule existed, and I just found the answer thanks to @orlp's comment under the question.

The code in the question seems to come from this 2014 blog post from KMOD'S BLOG, and was recently tweeted by Guido van Rossum.

And as someone asked about the reason why, Guido answered:

Backwards compatibility with Python 2.1.

So now we know...

这篇关于为什么在全局范围而不是封闭范围中查找未初始化的类变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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