2011-01-23 2 views
7

Почему не operator.iadd(x, y) эквивалент z = x; z += y? И Как operator.iadd(x, y) отличается от operator.add(x, y)?Как работают операторы на рабочем месте Python, отличные от стандартных функций оператора?

Из docs:

Многие операции имеют версию «на месте». Следующие функции обеспечивают более примитивный доступ к операциям на месте , чем обычный синтаксис ; например, оператор x + = y эквивалентен x = operator.iadd (x, y). Другой способ: сказать, что z = operator.iadd (x, y) эквивалентно составной оператор z = x; z + = y.

Related question, но меня не интересуют методы класса Python; просто регулярные операторы на встроенных типах Python.

ответ

21

Во-первых, вам нужно понять разницу между __add__ и __iadd__.

Метод __add__ объекта является обычным дополнением: он принимает два параметра, возвращает их сумму и не изменяет ни один из параметров.

Метод объекта __iadd__ также принимает два параметра, но делает изменение на месте, изменяя содержимое первого параметра. Поскольку для этого требуется мутация объекта, неизменяемые типы (например, стандартные типы номеров) не должны иметь метод __iadd__.

a + b использует __add__. a += b использует __iadd__, если он существует; если это не так, оно эмулирует его через __add__, как в tmp = a + b; a = tmp. operator.add и operator.iadd отличаются таким же образом.

К другой вопрос: operator.iadd(x, y) не эквивалентно z = x; z += y, потому что если нет __iadd__ не существует __add__ будет использоваться вместо этого. Вам необходимо присвоить значение, чтобы гарантировать, что результат будет сохранен в обоих случаях: x = operator.iadd(x, y).

Вы можете увидеть это сами достаточно легко:

import operator 
a = 1 
operator.iadd(a, 2) 
# a is still 1, because ints don't have __iadd__; iadd returned 3 

b = ['a'] 
operator.iadd(b, ['b']) 
# lists do have __iadd__, so b is now ['a', 'b'] 
+0

http://docs.python.org/2/reference/datamodel.html#object.__iadd__ Обратите внимание, что дополненная задания может, но не имеет изменить объект на месте – lig

+0

Почему питон разработан с расширенными заданиями, действующими на месте? Это похоже на контр-интуицию, потому что, когда мы изучаем язык, мы обычно сначала изучаем дополнительные задания с неизменяемыми значениями. Поэтому немного неожиданно, что с измененными значениями расширенное присваивание ведет себя по-разному. Чувствует себя скорее неявным и подверженным ошибкам. – max

0

Возможно, потому, что некоторые объекты Python неизменяемы.

Я предполагаю, что operator.iadd(x, y) эквивалентен z = x; z += y только для изменяемых типов, таких как словари и списки, но не для неизменяемых типов, таких как числа и строки.