2011-01-23 47 views
7

¿Por qué no es operator.iadd(x, y) equivalente a z = x; z += y? Y ¿cómo se diferencia operator.iadd(x, y) de operator.add(x, y)?¿Cómo son las funciones del operador in situ de Python diferentes a las funciones estándar del operador?

Desde el docs:

Muchas operaciones tienen una versión “in situ” . Las siguientes funciones proporcionan un acceso más primitivo a los operadores in situ que la sintaxis habitual; por ejemplo, la instrucción x + = y es equivalente a x = operator.iadd (x, y). Otra forma de poner es decir que z = operator.iadd (x, y) es equivalente a la sentencia compuesta z = x; z + = y.

Related question, pero no estoy interesado en los métodos de clase Python; solo operadores regulares en tipos de Python incorporados.

Respuesta

21

En primer lugar, debe comprender la diferencia entre __add__ y __iadd__.

El método __add__ de un objeto es una adición regular: toma dos parámetros, devuelve su suma y no modifica ninguno de los parámetros.

El método de un objeto __iadd__ también toma dos parámetros, pero realiza el cambio in situ, modificando el contenido del primer parámetro. Como esto requiere una mutación de objeto, los tipos inmutables (como los tipos de número estándar) no deben tener un método __iadd__.

a + b utiliza __add__. a += b usa __iadd__ si existe; si no lo hace, lo emula a través de __add__, como en tmp = a + b; a = tmp. operator.add y operator.iadd difieren de la misma manera.

Para la otra pregunta: operator.iadd(x, y) no es equivalente a z = x; z += y, porque si no existe __iadd__ existe __add__ se utilizará en su lugar. Debe asignar el valor para asegurarse de que el resultado se almacena en ambos casos: x = operator.iadd(x, y).

Se puede ver esto por sí mismo con bastante facilidad:

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__ en cuenta que podría aumentarse las asignaciones, pero no tiene para modificar el objeto in situ – lig

+0

¿Por qué Python está diseñado con asignaciones aumentadas que funcionan en el lugar? Es un poco intuitivo porque cuando aprendemos el idioma generalmente aprendemos tareas aumentadas con valores inmutables primero. Por lo tanto, es un poco inesperado que con valores variables la asignación aumentada se comporte de manera diferente. Se siente bastante implícito y propenso a errores. – max

0

Quizás porque algunos objetos de Python son inmutables.

Supongo que operator.iadd(x, y) es equivalente a z = x; z += y solo para tipos variables como diccionarios y listas, pero no para tipos inmutables como números y cadenas.

Cuestiones relacionadas