Python 中如果须要对一个变量进行增量运算通常有两种写法,a = a + b
或 a += b
。尽管两种办法可能失去同样的后果,但两者却并不齐全等价。
加法运算符 +
对于 a = a + b
这条语句来说,实际上执行了两步操作,首先执行 a + b
求出两者的 和
,而后再将后果通过赋值运算符 =
赋值给变量 a
。
来看上面的示例:
>>> a = 100
>>> b = 200
>>> id(a)
1796532544
>>> a = a + b
>>> a
300
>>> id(a)
17756816
>>> a = [11, 22, 33]
>>> b = [44, 55, 66]
>>> id(a)
54675856
>>> a = a + b
>>> a
[11, 22, 33, 44, 55, 66]
>>> id(a)
54676416
以上别离应用 Python 中的 不可变类型
和 可变类型
各列举了一个示例,并且在执行 a = a + b
语句的前后别离打印了变量 a
的 id
,能够看到无论对于 不可变类型
还是 可变类型
,最终变量 a
的 id
值都会扭转,阐明变量 a
在执行 a = a + b
当前指向了一片新的内存地址。这也比拟好了解,因为 a
曾经被从新赋值了。
增量赋值运算符 +=
对于运算符 +=
,咱们通常管它叫作 增量赋值运算符
,因为它即实现了 相加
操作,又实现了 赋值
操作。
同样,咱们还是别离用 int
和 list
两种数据类型来做演示:
>>> a = 100
>>> b = 200
>>> id(a)
1796532544
>>> a += b
>>> a
300
>>> id(a)
17756784
>>> a = [11, 22, 33]
>>> b = [44, 55, 66]
>>> id(a)
48777616
>>> a += b
>>> a
[11, 22, 33, 44, 55, 66]
>>> id(a)
48777616
对于 不可变类型
的操作,a += b
体现进去的后果和 a = a + b
雷同。而对于 可变类型
的操作却并不齐全一样。尽管最终变量 a
的 值
雷同,但执行 +=
操作后,变量 a
的内存地址并没有扭转,也就是说 +=
操作对于 可变类型
来说实际上是 就地更改
。对于 list
的操作,实际上 a += b
等价于 a.extend(b)
。
__add__
和 __iadd__
办法
实际上,在 Python 中,加法运算符 +
对应着对象的 __add__
办法,增量赋值运算符 +=
对应着对象的 __iadd__
办法。
无论对于 不可变类型
还是 可变类型
,当执行 a = a + b
时,都会调用 a
的 __add__
办法。而对于 a += b
的操作来说,当 a
为 不可变类型
时同样会调用 a
的 __add__
办法,当 a
为 可变类型
时会调用 a
的 __iadd__
办法进行 就地更改
,如果 a
没有实现 __iadd__
办法,那么才调用 a
的 __add__
办法。
咱们能够用 Python 内置的 hasattr
函数来验证下面的说法。
>>> hasattr(int, '__add__')
True
>>> hasattr(int, '__iadd__')
False
>>> hasattr(list, '__add__')
True
>>> hasattr(list, '__iadd__')
True
对于 不可变类型
来说,因为对象自身不可变,如果做相加操作必然会创立新的对象,所以也就没有 __iadd__
办法。而对于 可变类型
来说,对象自身可变,所以实现了 __iadd__
办法。
在咱们本人定义的类型中如果须要实现以上两个办法,也要遵循 Python 现有的标准,肯定要留神本人实现的类型是否可变,依据类型再来确定是否须要实现 __iadd__
办法。