请使用以下代码:
import something
def Foo():
something = something.SomeClass()
return something
Run Code Online (Sandbox Code Playgroud)
......这显然不是有效的代码:
UnboundLocalError: local variable 'something' referenced before assignment
Run Code Online (Sandbox Code Playgroud)
... something在=评估RHS之前,创建局部变量但未分配.(例如,参见相关答案的评论.)这对我来说似乎有点奇怪,但是当然,我会继续使用它.现在,为什么以下有效代码?
class Foo(object):
something = something.SomeClass()
Run Code Online (Sandbox Code Playgroud)
我的理解是class定义的内部基本上是一个范围:
然后使用新创建的本地命名空间和原始全局命名空间,在新的执行框架中执行类的套件(请参阅命名和绑定一节).
那么,为什么这些代码的行为与函数的行为不同?
类定义在本地范围内放置另一个命名空间.
Python的一个特殊之处在于 - 如果没有全局语句生效 - 对名称的赋值总是进入最内层范围.分配不复制数据 - 它们只是将名称绑定到对象.删除也是如此:语句del x删除了x与本地范围引用的命名空间的绑定.实际上,引入新名称的所有操作都使用本地范围:特别是,import语句和函数定义绑定本地范围中的模块或函数名称.(全局语句可用于指示特定变量存在于全局范围内.)
因此,在一个函数(或范围)的分配产生势必之前被访问的本地绑定变量,而在一个类定义它创建于上分配该类别的"命名空间"词典中的条目,允许的分辨率something来外部命名空间(模块命名空间).
请考虑以下示例,这可能有助于澄清这一点:
import datetime
class Foo(object):
datetime = datetime.datetime
>>> datetime
<module 'datetime' from '/usr/lib/python2.6/lib-dynload/datetime.so'>
>>> Foo.datetime
<type 'datetime.datetime'>
Run Code Online (Sandbox Code Playgroud)
请注意,该行datetime = datetime.datetime实际上是分配给名称的Foo.datetime,这与全局不一致datetime(就像在函数中使用相同的代码一样).
总之,由于类定义创建了新的命名空间以及新的范围,因此您可以直接访问封闭范围中的名称并在本地范围中指定相同的名称.