当引用全局变量时,我们可以看到函数和类对此的处理方式不同。第一个很好,第二个会导致错误:
x = 10
class Foo():
x = x + 1
a = foo()
Vs:
x = 10
def faa():
x = x + 1
faa()
In the Python执行模型 https://docs.python.org/3/reference/executionmodel.html#resolution-of-names,这被描述为:
类定义是可以使用和定义的可执行语句
名称。这些引用遵循名称解析的正常规则
例外情况是在中查找未绑定的局部变量
全局命名空间。
但为什么?
我遇到的唯一的其他提示是this bit https://docs.python.org/2.7/reference/compound_stmts.html#class-definitions:
然后该类的套件在新的执行框架中执行(参见
部分命名和绑定),使用新创建的本地命名空间和
原始的全局命名空间。 (通常,套件仅包含
函数定义。)当类的套件完成执行时,其
执行帧被丢弃,但其本地命名空间被保存。4 https://stackoverflow.com/questions/13905741/accessing-class-variables-from-a-list-comprehension-in-the-class-definition#13913933A
然后使用基类的继承列表创建类对象
类和属性字典保存的本地命名空间。
这仍然没有解释为什么这会导致在全局名称空间中查找未绑定的本地变量。
两个链接均来自这个答案 https://stackoverflow.com/questions/13905741/accessing-class-variables-from-a-list-comprehension-in-the-class-definition#13913933但这并没有更详细地说明原因。
正如中所解释的Python 常见问题解答 - 为什么我会收到 UnboundLocalError? https://docs.python.org/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
...因为当您对作用域中的变量进行赋值时,该变量将成为该作用域的本地变量,并隐藏外部作用域中任何类似命名的变量。由于 foo 中的最后一条语句为 x 分配了一个新值,因此编译器将其识别为局部变量。
因此,当早些时候尝试访问未初始化的局部变量时,会出现错误。
这解释了为什么:
x = 10
def foo():
x = x+1 # raises UnboundLocalError
foo()
引发异常,但不是这样:
x = 10
def faa():
y = x+1 # x stays in global scope, since it is not assigned in local
faa()
For the class foo()
这是一样的,因为 python 允许在任何给定时间将属性分配给对象。类代码分配x
作为对象的新属性a
.
x = 10
class foo():
x = x+1 # scope of x: class
a = foo() # x = 10; a.x = foo.x = 11
是相同的:
x = 10
class foo():
def __init__(self):
self.x = x+1 # scope of x: instance
a = foo() # x = 10; a.x = 11
显然在哪里self.x
被分配而不是x
,因此也处于全局范围内。 (也可以看看here http://blog.lerner.co.il/python-attributes/)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)