2012-03-19 4 views
9

рассмотрит следующий код:различного поведения для списка .__ iadd__ и списка .__ add__

>>> x = y = [1, 2, 3, 4] 
>>> x += [4] 
>>> x 
[1, 2, 3, 4, 4] 
>>> y 
[1, 2, 3, 4, 4] 

, а затем рассмотреть это:

>>> x = y = [1, 2, 3, 4] 
>>> x = x + [4] 
>>> x 
[1, 2, 3, 4, 4] 
>>> y 
[1, 2, 3, 4] 

Почему существует разница эти два?

(И да, я попытался найти это).

+4

Что интересно в вашем последнем заявлении, заключается в том, что эта функциональность фактически объясняется в документах python: http://docs.python.org/reference/datamodel.html#object.__add__ (из поиска этих терминов) – jdi

+3

@jdl: Да, я признаю, что я это не заметил. –

ответ

20

__iadd__ мутирует список, тогда как __add__ возвращает новый список, как показано.

Выражение x += y сначала пытается позвонить __iadd__, и, в противном случае, вызовы __add__ последовали за назначением (см. Комментарий Свена о незначительной коррекции). Так как list имеет __iadd__, тогда он делает это немного «магию мутации».

+1

Если вы хотите получить более подробную информацию об этом точном поведении и других соображениях относительно того, почему Python - это так, я бы очень рекомендовал [беседы о пифах python] (http://pyvideo.org/video/613/python-epiphanies) из PyCon 2012. Это приведет вас к большому количеству «ха!». моменты. –

+0

@S Сингх, если вы получите ответ, пожалуйста, выберите ответ в качестве принятого ответа и заполните рабочий процесс. В противном случае этот вопрос будет показан без ответа. – Nilesh

+1

Этот ответ немного вводит в заблуждение: назначение всегда выполняется независимо от того, вызывается ли '__iadd __()' или '__add __()'. 'list .__ iadd __()' просто возвращает 'self', тем не менее, поэтому присваивание не имеет никакого эффекта, кроме отображения локального целевого имени текущей области. –

3

Первый мутирует список, а второй повторяет имя.

Смежные вопросы