gpt4 book ai didi

python - python中关键字参数值的命名空间是什么?

转载 作者:行者123 更新时间:2023-12-01 00:11:31 24 4
gpt4 key购买 nike

我知道自从我发现以来,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.barself.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/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com