您好我对python中的变量范围有点困惑。请解释下面的片段之间的区别。
i)个
class Test(object):
a_var = 1
def a_func(self):
self.a_var = self.a_var + 1
print(self.a_var, '[ a_var inside a_func() ]')
if __name__=='__main__':
t=Test()
t.a_func()
O / P:2 [a_var in a_func()]
class Test(object):
a_var = 1
def a_func(self):
a_var = a_var + 1
print(a_var, '[ a_var inside a_func() ]')
if __name__=='__main__':
t=Test()
t.a_func()
o / p:UnboundLocalError:在赋值之前引用的局部变量'a_var'
为什么LEGB规则不适用于第二种情况,如果它没有从class的enclosedesope获取值。请解释一下。提前谢谢。
答案 0 :(得分:1)
这可能看起来很奇怪(而且确实如此),但是你不会在class
之上得到一个关闭,它只会超过def
。 " e nclosing" L E GB中提到的范围只是谈论函数定义;课程块不在此计算。
这种奇怪的行为是历史上将类添加到Python的方式的工件。类范围不是真正的范围。 Python并不总是有类,以及怪异的"中间范围"只是在类定义中存在:在内部,类主体下的代码或多或少只是在临时范围内运行exec
,结果被分配给类名。这是一个非常简单的"螺栓固定"当时将OOP引入语言的方法,以及Python将明确的self
事物作为有意的语言设计选择的原因。
从"类范围"访问a_var
在方法内部,您必须通过self.a_var
或Test.a_var
使用属性访问权限。两者都应该有效。您也可以在类定义期间直接在类级别访问它,但是因为您仍然在临时范围内,这只是本地访问的另一个示例( L EGB)。
execution model部分记录了这一点(尽管不是特别清楚)。
exec()和eval()的类定义块和参数在名称解析的上下文中是特殊的。类定义是可以使用和定义名称的可执行语句。这些引用遵循名称解析的常规规则,但在全局命名空间中查找未绑定的局部变量。类定义的名称空间成为类的属性字典。 类块中定义的名称范围仅限于类块;它没有扩展到方法的代码块 - 这包括了解和生成器表达式,因为它们是使用函数作用域实现的。