我知道自从我发现以来,python 就以不同的方式对待这个命名空间
def foo(l=[]):
l.append(1)
print(l)
foo()
foo()
foo([])
foo()
打印以下内容。
[1]
[1,1]
[1]
[1,1,1]
所以我对它们作为对象初始值设定项的使用持怀疑态度。
然后最近我遇到了另一个同样奇怪的行为,
下面演示。
class Foo:
bar = 0
def __init__(self):
self.a = bar
Foo()
这引发了一个异常
bar
未在此命名空间内定义。class Foo:
bar = 0
def __init__(self, a=bar)
self.a = a
Foo()
现在这成功地分配了类变量
foo
持有的值到一个对象 a
在初始化器里面。为什么会发生这些事情以及如何处理默认参数值?
最佳答案
三个事实:
def
类似的行为,这可能会令人惊讶。 . 第 3 点是最微妙的,可能与最初的预期相反。它记录在 execution model 中(第 4.2.2. 名称解析 ):
The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods
这就是名称
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
或 self.bar
.您现在应该明白为什么最后一个例子有效:
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: local variable referenced before assignment why LEGB Rule not applied in this case 中有更多关于奇怪的类作用域的信息。 .
关于python - python中关键字参数值的命名空间是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58313496/