理论上a + = b“将”b“添加到将结果存储在a中。 这种简单的描述将描述许多语言中的+ =运算符。
然而,简单的描述提出了几个问题。
“添加”究竟是什么意思?
“将结果存储在”中究竟是什么意思? python变量不直接存储值,它们存储对象的引用。
在python中,这两个问题的答案都取决于a的数据类型。
那么“添加”究竟是什么意思呢?
对于数字,它表示数字加法。
对于列表,元组,字符串等,它意味着连接。
请注意,对于列表+ =比+更灵活,列表上的+运算符需要另一个列表,但+ =运算符将接受任何可迭代。
那么“将价值存储在”中意味着什么呢?
如果对象是可变的,则鼓励(但不要求)就地执行修改。 所以指向它之前所做的相同对象,但该对象现在具有不同的内容。
如果对象是不可变的,那么它显然不能就地执行修改。 一些可变对象也可能没有就地“添加”操作的实现。 在这种情况下,变量“a”将被更新以指向包含加法运算结果的新对象。
从技术上讲,这是通过首先查找__IADD__来实现的,如果没有实现则尝试__ADD__,最后是__RADD__。
在变量中使用+ = python时需要注意我们不确定的确切类型,特别是在我们不确定类型是否可变的情况下。 例如,请考虑以下代码。
def dostuff(a):
b = a
a += (3,4)
print(repr(a)+' '+repr(b))
dostuff((1,2))
dostuff([1,2])
当我们用元组调用dostuff时,元组被复制为+ =操作的一部分,因此b不受影响。 但是,当我们使用列表调用它时,列表会在适当的位置进行修改,因此a和b都会受到影响。
在python 3中,使用“bytes”和“bytearray”类型观察到类似的行为。
最后请注意,即使未替换对象,也会发生重新分配。 如果左侧只是一个变量,这并不重要,但如果你有一个引用可变集合的不可变集合,它可能会导致混乱的行为,例如:
a = ([1,2],[3,4])
a[0] += [5]
在这种情况下,[5]将成功添加到[0]引用的列表中,但之后在代码尝试时将引发异常,并且无法重新分配[0]。