2013-09-15 4 views
0

Я положу код первого:Неожиданное поведение при использовании словаря в классе

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. Затем я изменил значение атрибута словаря на item item1 с помощью метода addValues. Проблема заключается в том, что добавление словарного атрибута item1 также добавляет то же значение в item2. Может ли кто-нибудь объяснить, что здесь происходит? Как изменилось значение item1 на значение item2? Я что-то забыл?

+3

Это происходит из-за использования '{}' (изменяемый словарь) как аргумент по умолчанию. На этом должно быть много дубликатов. – kennytm

+0

Возможный дубликат [«Наименьшее удивление» в Python: разрешимый аргумент по умолчанию] (http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument) –

+0

установить значение по умолчанию на «Нет» и обрабатывать его. –

ответ

1

Параметры по умолчанию оцениваются только один раз. Параметр value вашего init всегда будет таким же словарем, поэтому эффект мутирования его один раз при работе с одним экземпляром Item будет отображаться во всех других случаях Item.

От docs.python.org/2/reference/compound_stmts.html: значения параметров

по умолчанию вычисляются при определении функции выполняется. Это означает, что выражение оценивается один раз, когда функция определена, и что для каждого вызова используется одно и то же «предварительно вычисленное» значение. Это особенно важно для понимания, когда параметр по умолчанию является изменяемым объектом, таким как список или словарь: если функция изменяет объект (например, добавив элемент в список), значение по умолчанию изменяется. Обычно это не то, что было предназначено. Путь вокруг этого является использование None по умолчанию, и явно проверить его в теле функции, например:

def whats_on_the_telly(penguin=None): 
    if penguin is None: 
     penguin = [] 
    penguin.append("property of the zoo") 
    return penguin 
Смежные вопросы