类定义中的变量范围令人困惑
Posted
技术标签:
【中文标题】类定义中的变量范围令人困惑【英文标题】:Variable scopes inside class definitions are confusing 【发布时间】:2019-05-23 05:09:30 【问题描述】:由于某些原因,当出现这种情况时,python 从全局命名空间获取变量:
class Cls:
foo = foo
请看这段代码:
foo = 'global'
def func0():
foo = 'local'
class Cls:
bar = foo
print('func0', Cls.bar)
func0()
# func0 local
def func1():
foo = 'local'
class Cls:
foo = foo
print('func1', Cls.foo)
func1()
# func1 global
def func2():
foo = 'nonlocal'
def internal():
class Cls:
foo = foo
print('func2.internal', Cls.foo)
internal()
func2()
# func2.internal global
def func3():
foo = 'local'
class Cls:
bar = foo
foo = foo
print('func3', Cls.bar, Cls.foo)
func3()
# func3 global global
按照PEP 227
类定义是一个可执行语句,可能包含名称的使用和定义。这些引用遵循名称解析的正常规则。类定义的命名空间成为类的属性字典。
但在我看来,这根本不像是“遵循正常规则”。我错过了什么?
Py2 和 Py3 都是这样操作的。
【问题讨论】:
@DeepSpace 我期待赋值右侧的评估应该独立于左侧的变量名,但这里不是这种情况。当您在类定义中执行a = b
时,它会从本地命名空间获得 b
,但随后 a = a
它会从全局命名空间获得正确的 a
a
还能从哪里获得?
来自本地命名空间,请查看func0
。
在我看来,它应该像在函数的命名空间中一样引发UnboundLocalError
,但由于某些原因它不会
【参考方案1】:
Execution model - Resolution of names:
中记录了这一点类定义块 [...] 是特殊的 在名称解析的上下文中。类定义是可执行文件 可以使用和定义名称的语句。这些参考遵循 名称解析的正常规则,unbound local 除外 在全局命名空间中查找变量。
(强调我的)
【讨论】:
谢谢,这就是我要找的!也许您可以提供任何有关这种行为动机的见解?以上是关于类定义中的变量范围令人困惑的主要内容,如果未能解决你的问题,请参考以下文章