kuc*_* 23 5 python arguments python-3.x
我知道自从我发现 python 以不同的方式对待这个命名空间
def foo(l=[]):
l.append(1)
print(l)
foo()
foo()
foo([])
foo()
Run Code Online (Sandbox Code Playgroud)
打印以下内容。
[1]
[1,1]
[1]
[1,1,1]
Run Code Online (Sandbox Code Playgroud)
所以我对它们用作对象初始值设定项持怀疑态度。最近我遇到了另一个类似的奇怪行为,如下所示。
class Foo:
bar = 0
def __init__(self):
self.a = bar
Foo()
Run Code Online (Sandbox Code Playgroud)
这会引发异常,因为bar该命名空间内未定义。
class Foo:
bar = 0
def __init__(self, a=bar)
self.a = a
Foo()
Run Code Online (Sandbox Code Playgroud)
现在,这成功地将类变量持有的值分配给初始化器内的foo对象。a为什么会发生这些事情以及如何处理默认参数值?
三个事实:
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
Run Code Online (Sandbox Code Playgroud)
请注意bar,值0仍然可以作为类属性从方法内访问:通过Foo.bar或self.bar。
您现在应该明白为什么最后一个示例有效:
class Foo:
bar = 0
def __init__(self, a=bar):
self.a = a
Foo()
Run Code Online (Sandbox Code Playgroud)
并且,考虑到上面的第 1-3 点,您还应该能够正确预测这里会发生什么:
class Foo:
def __init__(self, a=bar):
self.a = a
bar = 0
Foo()
Run Code Online (Sandbox Code Playgroud)
有关奇怪的类作用域的更多信息,请参见UnboundLocalError: local variable referenced before assignment Why LEGB Rule not apply in this case。
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |