【问题标题】:Optional keyword argument being filled with non-default value unless specified [duplicate]除非指定,否则用非默认值填充可选关键字参数
【发布时间】:2021-10-09 03:53:38
【问题描述】:

我有一个函数 create,它接受这些参数:

create(self, name, val={})

它是一个类的一部分,该类有一个名为 val 的属性,因此请注意 valself.val 是两个不同的对象。

不知何故,val 的值已被 self.val 替换,这导致我的模块中出现一些递归问题。

有问题的模块名为pyndb,基本上采用字典并用自定义Node 对象表示每个键。然后这些对象对它们持有的所有键执行相同的过程(如果键的值是另一个字典)。如果有帮助,我已经记录了整个模块 here

如果您查看模块和重现此错误的具体过程,正如我详细介绍的here,您会注意到这只发生在尝试在主类内部创建第三个对象时。所述对象的值应该是一个空字典,因为我没有更改 val 参数的默认值。但是,如果我手动将val 设置为空字典,则没有问题。

最让我难过的部分是为什么这只影响第三个Node向内。

该模块的源代码在我上面链接的 GitHub 存储库中,该模块可以通过 pip 安装:

pip3 install pyndb

任何帮助将不胜感激。

【问题讨论】:

  • 1) 请更新您的问题以包含一个独立的minimal, reproducible example。我们不能接受指向外部网站的链接。 2) 看起来您的问题可能是由于 create 使用可变默认参数所致。如果create 在任何地方将val 分配给self.val,那么在所有使用默认参数的后续调用中,您最终可能会得到val 引用与self.val 相同的对象。见“Least Astonishment” and the Mutable Default Argument
  • 这很有意义,因为我已经阅读了该帖子上接受的答案。我没有意识到关键字参数只定义了一次,并且可以像这样更改。感谢您的帮助

标签: python python-3.x recursion


【解决方案1】:

我不确定我是否特别理解这个问题,但我怀疑您的问题来自使用可变对象作为默认变量。举个例子,假设我有一个函数

def add_to_list(item, l=[]):
    l.append(item)
    return l

如果我得到你所期望的之后再调用它

>>> add_to_list(1)
[1]

但是,这已经永久改变了l 默认变量的值,这意味着如果我现在输入

>>> add_to_list(2)
[1,2]

我得到了两个元素而不是一个。

我建议解决您的问题

def create(self, name, val=None):
    if not val:
        val = {}

作为一种解决方法。

【讨论】:

    猜你喜欢
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    • 2021-03-13
    • 1970-01-01
    相关资源
    最近更新 更多