小编典典

UnboundLocalError:分配前引用了局部变量,为什么在这种情况下不应用LEGB规则

python

嗨,我对python中变量的作用域感到困惑。请解释以下片段之间的区别。

一世)

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_func()内部的a_var]

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规则,它是否不能从类的封闭对象中获取值。请解释。提前致谢。


阅读 163

收藏
2021-01-20

共1个答案

小编典典

这似乎很奇怪(确实如此),但是 您并没有结束class,只是结束了def。该“ ê 以L简称nclosing”范围 ê
GB只是说说函数定义; 类块在这里不算在内。

这种奇怪的行为是历史上将类添加到Python的方式的产物。类范围不是实际范围。Python并不总是具有类,而怪异的“中间作用域”仅在类定义期间存在:在内部,类主体下的代码或多或少地只是exec在临时作用域下运行,并将结果分配给类名。当时,这是一种非常简单的“螺栓连接”方法,可将OOP纳入该语言,这也是Python之所以将明确的self东西作为有意的语言设计选择的原因。

要从a_var方法内部从“类范围”访问,您将必须通过self.a_var或使用属性访问Test.a_var。两者都应该起作用。您也可以在类定义期间在类级别直接访问它,但是由于您仍在临时范围内,这只是本地访问的另一个示例(
L EGB)。

执行模型部分中对此进行了记录(尽管不是特别清楚)。

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

2021-01-20