答案 0 :(得分:19)
这是Python的名称解析规则的工件:您只能访问全局范围和本地范围,但不能访问中间范围,例如:不是你的直接外部范围。
编辑:以上措辞不当,您做可以访问外部作用域中定义的变量,但是通过执行x = x
或{{1}从一个非全局命名空间,你实际上用你在本地定义的那个掩盖了外部变量。
在示例2中,您的直接外部范围是全局范围,因此mymethod = mymethod
可以看到MyClass
,但在示例4中,您的直接外部范围是mymethod
,因此它不能,因为my_defining_func()
的外部定义已经被其本地定义所掩盖。
有关非本地名称解析的详细信息,请参阅PEP 3104。
另请注意,由于上述原因,我无法在Python 2.6.5或3.1.2下运行示例3:
mymethod
但以下情况可行:
>>> def myfunc():
... x = 3
... class MyClass(object):
... x = x
... return MyClass
...
>>> myfunc().x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in myfunc
File "<stdin>", line 4, in MyClass
NameError: name 'x' is not defined
答案 1 :(得分:5)
这篇文章已有几年历史了,但是在Python中讨论范围和静态绑定的重要问题是很少见的。然而,对于例子3的作者存在一个重要的误解,可能会使读者感到困惑。 (不要认为其他的都是正确的,只是我只详细讨论了例3中提出的问题)。 让我澄清一下发生了什么。
在例3中
def myfunc():
x = 3
class MyClass(object):
x = x
return MyClass
>>> myfunc().x
必须返回错误,不像帖子的作者所说的那样。我相信他错过了错误,因为示例1 x
已在全局范围内分配给3
。因而错误地理解了所发生的事情。
这篇文章详细描述了这种解释 How references to variables are resolved in Python