关于类:python:dictionary作为实例变量

Python: Dictionary as instance variable

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument

对于字典作为Python3中的类实例变量的行为,我非常困惑。我理解它的方式是,Python中的实例变量具有每个实例的存储,而类变量是每个类的(类似于其他一些语言所称的"静态")。

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

1
2
3
4
5
6
7
8
9
class Foo:
    def __init__(self, values = dict()):
        self.values = values

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

f2 = Foo()
print(f2.values)

该程序输出:

1
{'hello': 'world'}

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

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

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

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


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

如果要使用默认参数,请使用None并检查它:

1
2
3
4
if values is None:
    self.values = {}
else:
    self.values = values


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

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

如果你提供一个values,那就可以用了。如果没有,valuesor操作符评估为FALSE并实例化一个新的dict。