Python:字典作为实例变量
可能重复的问题:
Python中的“最小惊讶”:可变的默认参数
我对Python 3中字典作为类实例变量的行为感到很困惑。我的理解是,Python中的实例变量是针对每个实例单独存储的,而类变量是针对整个类的(这和其他一些语言中的“静态”变量类似)。
这种理解似乎是正确的,但当实例变量是一个从默认参数创建的字典时,就出现了问题。例如:
class Foo:
def __init__(self, values = dict()):
self.values = values
f1 = Foo()
f1.values["hello"] = "world"
f2 = Foo()
print(f2.values)
这个程序的输出是:
{'hello': 'world'}
咦?为什么实例 f2
和 f1
有相同的字典实例呢?
如果我不传递一个空字典作为默认参数,而是明确地将 self.values
赋值为一个空字典,我就能看到预期的行为:
class Foo:
def __init__(self):
self.values = dict()
但我不明白为什么这样会有任何区别。
2 个回答
3
默认值只会被计算一次。如果你想要的效果是这样的:
class Foo:
def __init__(self, values = None):
self.values = values or dict()
如果你提供了一个 values
,那么这个值会被使用。如果没有提供,values
会被 or
操作符当作 FALSE
来处理,这样就会创建一个新的字典。
19
这是Python中一个大家都知道的惊喜。默认参数是在函数定义的时候就被计算出来的,而不是在函数被调用的时候。所以你的默认参数其实是指向一个公共的dict
。这和把它赋值给类或实例变量没有关系。
如果你想使用默认参数,建议用None
,然后再进行检查:
if values is None:
self.values = {}
else:
self.values = values