UnboundLocalError:在赋值之前引用的局部变量为什么在这种情况下不应用LEGB规则

时间:2017-07-19 15:34:13

标签: python

您好我对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获取值。请解释一下。提前谢谢。

1 个答案:

答案 0 :(得分:1)

这可能看起来很奇怪(而且确实如此),但是你不会在class之上得到一个关闭,它只会超过def 。 " e nclosing" L E GB中提到的范围只是谈论函数定义;课程块不在此计算。

这种奇怪的行为是历史上将类添加到Python的方式的工件。类范围不是真正的范围。 Python并不总是有类,以及怪异的"中间范围"只是在类定义中存在:在内部,类主体下的代码或多或少只是在临时范围内运行exec,结果被分配给类名。这是一个非常简单的"螺栓固定"当时将OOP引入语言的方法,以及Python将明确的self事物作为有意的语言设计选择的原因。

从"类范围"访问a_var在方法内部,您必须通过self.a_varTest.a_var使用属性访问权限。两者都应该有效。您也可以在类定义期间直接在类级别访问它,但是因为您仍然在临时范围内,这只是本地访问的另一个示例( L EGB)。

execution model部分记录了这一点(尽管不是特别清楚)。

  

exec()和eval()的类定义块和参数在名称解析的上下文中是特殊的。类定义是可以使用和定义名称的可执行语句。这些引用遵循名称解析的常规规则,但在全局命名空间中查找未绑定的局部变量。类定义的名称空间成为类的属性字典。 类块中定义的名称范围仅限于类块;它没有扩展到方法的代码块 - 这包括了解和生成器表达式,因为它们是使用函数作用域实现的。