Python 中逗号赋值语句 a = a, b = b, a 的执行机制解析

该语句看似混乱,实则遵循 python 的赋值链解析规则:它先构建元组 `(b, a)` 并赋值给 `a`,再将该元组解包回 `a` 和 `b`,最终实

现变量交换——但 `a` 会经历“临时变元组→被解包覆盖”的过程。

在 Python 中,a = a, b = b, a 是一条复合赋值语句(compound assignment),而非两个独立赋值。它等价于:

a, b = b, a

但执行过程更复杂:Python 将其解析为 “先计算右侧表达式,再依次赋值” 的链式操作。关键在于,a, b = b, a 本身是原子性的解包赋值,而 a = a, b = b, a 实际上被解释为:

# 等效逻辑(非语法合法,仅示意执行顺序):
temp = (b, a)   # 构建元组:(20, 10)
a = temp        # 此时 a 变为元组 (20, 10)
a, b = temp     # 解包 temp → a=20, b=10

可通过字节码验证这一行为(以 Python 3.11 为例):

import dis

def swap_demo():
    a = 10
    b = 20
    a = a, b = b, a

dis.dis(swap_demo)

输出关键字节码片段:

10 LOAD_FAST                1 (b)        # 加载 b (20)
12 LOAD_FAST                0 (a)        # 加载 a (10)
14 BUILD_TUPLE              2            # 构建元组 (20, 10)
16 COPY                     1            # 复制该元组(为后续解包准备)
18 STORE_FAST               0 (a)        # 将元组存入 a → a = (20, 10)
20 UNPACK_SEQUENCE          2            # 解包元组
24 STORE_FAST               0 (a)        # 第一个元素 → a = 20
26 STORE_FAST               1 (b)        # 第二个元素 → b = 10

可见:a 先被赋值为元组,紧接着又被解包覆盖——因此最终 a 不是元组,而是 20;b 变为 10。

⚠️ 重要提醒

  • 此写法属于未文档化、高度依赖实现细节的晦涩语法,CPython 解释器虽当前支持,但官方从未保证其稳定性;
  • 它违反可读性原则,极易引发误解(如误以为 a 会保留元组);
  • 在 PyPy、Jython 或未来 CPython 版本中可能被禁用或行为变更;
  • 绝对不应出现在生产代码中。标准、安全、清晰的交换写法永远是:
a, b = b, a  # ✅ 推荐:原子性、可读、跨版本兼容

或显式使用临时变量:

temp = a
a = b
b = temp  # ✅ 明确、易调试,适合复杂逻辑

总结:a = a, b = b, a 是字节码层面的“副作用巧合”,不是设计特性。理解其原理有助于深入掌握 Python 赋值机制,但实践中请坚决使用 a, b = b, a —— 简洁即强大,清晰即可靠。