当前位置 : 主页 > 编程语言 > python >

Python教程:序列的增量赋值

来源:互联网 收集:自由互联 发布时间:2022-06-18
增量赋值运算符有 += 和 *=。+= 背后的特殊方法是 ​​__iadd__​​​,如果一个类没有实现 ​​__iadd__​​​方法,Python 会退一步调用 ​​__add__​​​方法。这两个方法的区别在于,​


增量赋值运算符有 += 和 *=。+= 背后的特殊方法是 ​​__iadd__​​​,如果一个类没有实现 ​​__iadd__​​​方法,Python 会退一步调用 ​​__add__​​​方法。这两个方法的区别在于,​​__iadd__​​​为就地改动,不会改变原值的内存地址,而 ​​__add__​​方法会得到一个新对象。

考虑下面一个表达式:

a += b

如果 a 实现了​​__iadd__​​​ 方法,a 会就地改动(内存地址不变)。如果 a 没有实现​​__iadd__​​方法,那么 a += b 这个表达式的效果就变得跟 a = a + b 一样了,生成一个新的对象赋给 a。

总体来讲,可变序列一般都实现了​​__iadd__​​ 方法,因此 += 是就地加法,而不可变序列根本就不支持这个操作。

​​*=​​​和 ​​+=​​​ 一样,只是背后的特殊方法为​​__imul__​​。

a = [1, 2, 3]
b = [4, 5, 6]
print("id(a) = %d" % id(a))
a += b
print("id(a) = %d" % id(a))

c = [1, 2, 3]
print("id(c) = %d" % id(c))
c = c + b
print("id(c) = %d" % id(c))

d = (1, 2, 3)
print("id(d) = %d" % id(d))
d *= 2
print("id(d) = %d" % id(d))

运行结果如下:

id(a) = 1298277978824
id(a) = 1298277978824
id(c) = 1298277978696
id(c) = 1298277978632
id(d) = 1298277972872
id(d) = 1298277136616

了解了序列的增量赋值,我们来看 Leonardo Rochael 在 2013 年的 Python 巴西会议上提到的谜题:

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
t = (1, 2, [30, 40])
t[2] += [50, 60]

A. t 变成 (1, 2, [30, 40, 50, 60])

B. 因为 tuple 不支持对它的元素赋值,所以会抛出 TypeError 异常

C. 以上两个都不是

D. A 和 B 都是对的

估计很多人会跟我一样选 B,但其实答案是 D。

在控制台运行代码,显示结果如下:

Python教程:序列的增量赋值_内存地址

总结:

1、对不可变序列进行重复拼接操作的话,效率会很低,因为每次都要新建一个序列,然后把原来序列中的元素复制到新的序列里,然后再追加新的元素。

2、不要把可变对象放在元组里面。

3、增量赋值不是一个原子操作,我们刚才也看到了,它虽然抛出了异常,但 t 的值还是改变了。



网友评论