【问题标题】:Python: Dictionary as instance variable [duplicate]Python:字典作为实例变量
【发布时间】:2011-08-26 15:08:24
【问题描述】:

可能重复:
“Least Astonishment” in Python: The Mutable Default Argument

我对字典在 Python 3 中作为类实例变量的行为感到非常困惑。根据我的理解,Python 中的实例变量具有 per-instance 存储,不像类变量是 per -class(类似于某些其他语言所说的“静态”)。

这似乎是正确的,除非实例变量是从默认参数创建的字典。例如:

class Foo:
    def __init__(self, values = dict()):
        self.values = values

f1 = Foo()
f1.values["hello"] = "world"

f2 = Foo()
print(f2.values)

这个程序输出:

{'hello': 'world'}

嗯?为什么实例f2f1 具有相同的字典实例?

如果我不将空字典作为默认参数传递,我会得到预期的行为,只需将 self.values 明确分配给空字典:

class Foo:
    def __init__(self):
        self.values = dict()

但我不明白为什么这会有什么不同。

【问题讨论】:

  • 可能是默认参数仅在加载类时评估一次。这样,您只需将相同的引用分配为默认参数。
  • 堆栈溢出对每个标签都有一个很好的“常见问题解答”功能。以下是 Python 标记的常见问题解答:stackoverflow.com/questions/tagged/… 您的问题已在问题编号 4 中得到解答。

标签: python class dictionary python-3.x


【解决方案1】:

这是 Python 中众所周知的惊喜。默认参数是在定义函数时评估的,而不是在调用它时评估的。因此,您的默认参数是对常见dict 的引用。它与将其分配给类/实例变量无关。

如果要使用默认参数,请使用None,并勾选:

if values is None:
    self.values = {}
else:
    self.values = values

【讨论】:

  • 使用列表也会得到相同的行为
  • 每一个可变对象都会得到相同的行为。
【解决方案2】:

默认值只计算一次。你想要这样的东西:

 class Foo:
     def __init__(self, values = None):
         self.values = values or dict()

如果您提供values,它将被使用。如果不是,values 将由 or 运算符评估为 FALSE 并实例化一个新的字典。

【讨论】:

  • 如果任何错误的值作为值传递,这将失败 - 例如自定义 dict 子类的空实例。
猜你喜欢
  • 1970-01-01
  • 2018-11-11
  • 2017-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多