在类中使用字典时出现意外行为

时间:2013-09-15 15:44:01

标签: python dictionary

我会把代码放在第一位:

Python 2.7.3 (default, Aug  1 2012, 05:16:07) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> class Item(object):
...     def __init__(self, name, value={}):
...         self.name = name
...         self.value = value
...     def __str__(self):
...         return self.name + " - " + str(self.value)
...     def addValues(self, value):
...         for key,price in value.iteritems():
...             self.value[key] = price
... 
>>> 
>>> item1 = Item('car')
>>> print item1
car - {}
>>> item2 = Item('truck')
>>> print item2
truck - {}
>>> item1.addValues({'blue':6000})
>>> print item1
car - {'blue': 6000}
>>> print item2
truck - {'blue': 6000}
>>> 

我创建了类Item,item1和item2的两个实例。然后,我使用addValues方法更改了对象item1上的dictionary属性的值。问题是,添加item1的字典属性,也为item2添加了相同的值。有人能解释一下这里发生了什么吗? item1上的值更改如何更改item2上的值?我忽略了什么吗?

1 个答案:

答案 0 :(得分:1)

默认参数仅评估一次。 value的{​​{1}}参数将始终是相同的字典,因此在处理一个init实例时将其变更一次的效果将全部显示在其他Item个实例。

来自docs.python.org/2/reference/compound_stmts.html

  

执行函数定义时会计算默认参数值。这意味着在定义函数时,表达式将被计算一次,并且相同的“预先计算”值将用于每次通话。这对于理解默认参数何时是可变对象(例如列表或字典)尤其重要:如果函数修改对象(例如,通过将项附加到列表),则默认值实际上被修改。这通常不是预期的。解决这个问题的方法是使用Item作为默认值,并在函数体中明确地测试它,例如:

None