2011-01-23 33 views
7

为什么不是operator.iadd(x, y)相当于z = x; z += yoperator.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__。如果它存在,则使用使用__iadd__;如果没有,则通过__add__模拟它,如tmp = a + b; a = tmpoperator.addoperator.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 2014-02-25 16:47:21

0

也许是因为一些Python对象是不可变的。

我猜operator.iadd(x, y)相当于z = x; z += y只适用于可变类型,如字典和列表,但不适用于像数字和字符串这样的不可变类型。