奇怪的 +=

看《Fluent Python》看到这一部分,感觉很有收获。分享一下。


引例

判断一下下面Python程序语句的运行结果:

t = (1, 2, [30, 40])
t[2] += [50, 60]

选项:

a>. t 变为 (1, 2, [30, 40, 50, 60])
b>. TypeError: 'tuple' object does not support item assignment
c>. 没有正确答案
d>. a, b 都是

你的选项是什么?

正确答案: d>


分析

一个很有用的网站:http://www.pythontutor.com 可以一步步地显示程序的运行过程:


奇怪的 +=_第1张图片

一个有用的包:

奇怪的 +=_第2张图片
运算过程

s[a] += b的过程分析:

  • 将 s[a] 的值放到栈顶TOS
  • 执行TOS += b, 如果TOS指向的是一个可变对象,则可以成功执行
  • 将TOS赋值给 s[a]: s[a] = TOS, 如果s 是不可变的,操作会失败。

所以,开始的问题就是这么个流程:

  • 将 t[2] 即: [30, 40] 放到栈顶,作为TOS
  • 执行 [30, 40] += [50, 60]
  • 将TOS(此时即[30, 40, 50, 60])赋值回 t[2] 时,因为 t 是 tuple , 是不可变的,操作失败,抛出异常

收获:

  • 尽量不要在 tuple 中存放可变对象
  • +=, *=等操作不是原子操作
  • dis 模块查看Python字节码详细执行过程
  • http://www.pythontutor.com 可以一步步地显示程序的运行过程

你可能感兴趣的:(奇怪的 +=)