python关于+=的陷阱

本文探讨了为何在Python中,尽管元组被视为不可变,但尝试修改其内部可变元素仍可能导致异常。通过实例和Python Tutor可视化,揭示了可变对象与元组结合的复杂性,以及增量赋值操作在元组中的非原子性。关键教训是避免在元组中包含可变元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看下面代码

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

我们知道tuple元组是个不可变元素,所以更改元组的元素道理上是不行的,但是我改变的元素是个列表,它本身是可变的,这样可行吗??

先别去控制台运行,猜是下面哪一种:

  1. t 变成 (1, 2, [30, 40, 50, 60])。
  2. 因为 tuple 不支持对它的元素赋值,所以会抛出 TypeError 异常。
  3. 以上两个都不是。
  4. a 和 b 都是对的。

\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\

\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
答案是第四种情况

我们使用Python Tutor(http://www.pythontutor.com)对执行代码进行可视化
在这里插入图片描述在这里插入图片描述
最后我们看看背后的字节码是怎么执行s[a] += b这种操作的
在这里插入图片描述到1是将 s[a] 的值存入 TOS(Top Of Stack,栈的顶端)
到2是计算 TOS += b。这一步能够完成,是因为 TOS 指向的是一个可变对象
到3是s[a] = TOS 赋值。这一步失败,是因为 s 是不可变的元组

所以才会出现即操作成功又报异常的现象

教训:

  1. 不要把可变对象放在元组里面
  2. 增量赋值不是一个原子操作(从字节码可以看出经过了若干步)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值