python - 为什么在全局范围而不是封闭范围中查找未初始化的类变量?

标签 python function class variables

这不是我编码项目需要的问题,但是我的一个 friend 把这个发给了我。
问题是:这里打印出什么?为什么?

x = 0
y = 0
def f():
    x = 1
    y = 1
    class A:
        print(x,y)
        x = 2
f()
输出:
0 1
我的第一直觉告诉我应该是“1 1”,但我错了。我摆弄了代码,发现如果我删除“x = 2”我会是正确的。但为什么?
此外,当我将变量设为全局时,它也起作用了。像这样:
x = 0
y = 0
def f():
    global x
    global y
    x = 1
    y = 1
    class A:
        print(x,y)
        x = 2
f()
输出:
1 1
我不是在寻找问题的其他解决方案,只是更好地了解这里发生的事情。
提前致谢

最佳答案

这记录在 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)


所以,y正如预期的那样,在定义它的最近的封闭范围中查找(f 函数,它得到值 1)。
在另一端,x = 2导致 x 被认为是本地的,因为它尚未在 print(x,y) 中定义,异常会导致它在全局命名空间中被查找(它的值是 0),而不是导致 NameError ,正如正常函数中未绑定(bind)的局部变量所预期的那样。

我一直想知道为什么这个特殊规则存在,感谢@orlp 在问题下的评论,我才找到了答案。
问题中的代码似乎来自this 2014 blog post from KMOD'S BLOG , 最近是 tweeted by Guido van Rossum .
正如有人问及原因,Guido answered :

Backwards compatibility with Python 2.1.


所以现在我们知道...

关于python - 为什么在全局范围而不是封闭范围中查找未初始化的类变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66126464/

相关文章:

c++ - 层次结构中类的编译器错误

python - 无法连接到我要上传文件的 dash 应用程序的服务器错误

python - 并行过程的最佳种子

python - Airflow 在 Python 运算符之间传递数据帧

javascript - 用于突出显示功能的更高效的 JavaScript 代码?

arrays - MATLAB - 避免元胞数组内向量中的重复值并取下一个

php - 了解在 OOP 中返回和传递自定义对象的目的

java - 如何从 C 中加载和调用 java 编译的类?

python - Dask 分布式诊断网页无法正常工作

function - 将可选回调传递给 Swift 函数