Python 的就地运算符函数和标准运算符函数有什么不同?

15 投票
2 回答
16656 浏览
提问于 2025-04-16 10:27

来自文档的内容:

很多操作都有一个“就地”版本。以下这些函数提供了一种比通常语法更基础的方式来使用就地操作符;比如,语句 x += y 和 x = operator.iadd(x, y) 是等价的。换句话说,z = operator.iadd(x, y) 和复合语句 z = x; z += y 是一样的。

问题:

  • 为什么 operator.iadd(x, y) 不等于 z = x; z += y?

  • operator.iadd(x, y)operator.add(x, y) 有什么不同?

相关问题,但我对Python类方法不感兴趣;只想了解内置Python类型上的普通操作符。

2 个回答

0

可能是因为有些Python对象是不可变的。

我猜operator.iadd(x, y)的意思和z = x; z += y是一样的,只对像字典和列表这样的可变类型有效,而对像数字和字符串这样的不可变类型就不适用了。

32

首先,你需要明白 __add____iadd__ 之间的区别。

一个对象的 __add__ 方法是普通的加法:它接收两个参数,返回它们的和,并且不会改变这两个参数的值。

而一个对象的 __iadd__ 方法也是接收两个参数,但它会直接在第一个参数上进行修改,也就是说,它会改变第一个参数的内容。因为这种修改会改变对象本身,所以不可变类型(比如普通的数字类型)不应该有 __iadd__ 方法。

a + b 使用的是 __add__。而 a += b 如果存在 __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']

撰写回答