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

标签 python python-3.x arguments

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

    相关文章:

    python - 检查字符串的格式

    python - 在 Python 中使用 super(),我不明白最后一次调用 __init__

    python - __init__ OSError : [Errno 24] Too many open files中的 “/usr/lib/python3.5/socket.py”文件,第134行

    qt - 'QMessageBox::critical':4 个重载中没有一个可以转换所有参数类型

    python - SQLite3 查询 ORDER BY 参数与?符号

    python - 为什么在使用 pyqt 时 PyCharm 中的 python 控制台不显示任何错误消息?

    python - 如何在Python中将本地时间的日期/时间字符串转换为UTC?

    python-3.x - python tkinter 在打开文件时更新标签的内容

    python - 如何定义带有可选参数的函数?

    c++ - 是否可以使函数对常量参数或变量参数表现不同?