三个事实:
- The name默认参数的(左侧)是函数体内的局部变量名称。
- The value默认参数的(右侧)在函数定义时在定义函数的范围内求值。
- 类块中的代码在类定义期间在临时命名空间中执行。类块不被视为封闭范围,如果您期望类似于嵌套的行为,这可能会令人惊讶
def
.
第三点是最微妙的,也许与最初的预期相反。它记录在执行模型(部分4.2.2.名称解析):
类块中定义的名称范围仅限于该类块;它不会扩展到方法的代码块
这就是这个名字的由来bar
在你的第二个例子中没有解决:
class Foo:
bar = 0
def __init__(self):
self.a = bar # name "bar" isn't accessible here, but code is valid syntax
Foo() # NameError: name 'bar' is not defined
注意bar
value, 0
,仍然可以从方法内部作为类属性进行访问:通过Foo.bar
or self.bar
.
你现在应该明白为什么最后一个例子does work:
class Foo:
bar = 0
def __init__(self, a=bar):
self.a = a
Foo()
而且,考虑到上面的第 1-3 点,您还应该能够正确预测这里会发生什么:
class Foo:
def __init__(self, a=bar):
self.a = a
bar = 0
Foo()
有更多关于奇怪的类范围的信息UnboundLocalError:分配之前引用的局部变量为什么在这种情况下不应用 LEGB 规则.