这是我在有关此功能的古老答案中所做的内容:
您遇到的问题是由于以下原因:
块是作为一个单元执行的一段 Python 程序文本。以下是块:模块、函数体和类定义。
(...)
范围定义了名称在块中的可见性。
(...)
类块中定义的名称范围仅限于类块;它没有扩展到方法的代码块——这包括生成器表达式,因为它们是使用函数范围实现的。这意味着以下将失败:
A类:
a = 42
b = list(a + i for i in range(10))
http://docs.python.org/reference/executionmodel.html#naming-and-binding
上面的意思是:函数体是代码块,方法是函数,那么在类定义中存在的函数体之外定义的名称不会扩展到函数体。
当我读到这篇文章时,这对我来说似乎很奇怪,但这就是 Python 的制作方式:
类块中定义的名称范围仅限于类块;它没有扩展到方法的代码块
官方文档就是这么说的。
.
编辑
heltonbiker写了一段有趣的代码:
COLOR = 'blue'
class TellColor(object):
COLOR = 'red'
def tell(self):
print self.COLOR # references class variable
print COLOR # references module variable
a = TellColor()
a.tell()
> red
> blue
这让我想知道print COLOR
在方法内部编写的指令如何tell()
引发打印在类外部定义的全局对象 COLOR 的值。
我在官方文档的这一部分找到了答案:
方法可以像普通函数一样引用全局名称。与方法关联的全局范围是包含其定义的模块。(类从不用作全局范围。)虽然很少遇到在方法中使用全局数据的充分理由,但全局范围有许多合法用途:一方面,导入全局范围的函数和模块可以被方法以及其中定义的函数和类使用。通常,包含该方法的类本身是在这个全局范围内定义的(...)
http://docs.python.org/2/tutorial/classes.html#method-objects
当解释器必须执行print self.COLOR
时,由于COLOR不是实例属性(也就是说标识符 'COLOR' 不属于实例的命名空间),解释器进入实例类的命名空间搜索标识符“COLOR”并找到它,因此它会打印出TellColor.COLOR的值
当解释器必须执行print COLOR
时,由于该指令中没有写入属性访问,它将在全局命名空间中搜索标识符“COLOR”,官方文档说它是模块的命名空间。