正如 norok 所指出的,存储和装载是从不同的方向进行的。如果我们使用下面的代码,我们可以看到 python 在底层做了什么。
import dis
def foo():
a, b, c = 1, 2, 3
a, b, c = c, a, b = b, a, c = c, b, a
dis.dis(foo)
下面是字节码。在 cmets 的右侧,您可以看到变量 a、b 和 c 的值以及操作结束时的内存堆栈。您将看到DUP_TOP 命令在各个步骤中否定分配,因此只有第一次加载和最后一次存储似乎可以执行任何操作。这也可以解释为什么 a, b, c = a, a, a = b, b, b = c, c, c = b, a, c = c, b, a 仍然评估为 (2, 3, 1)。
# a b c stack
4 0 LOAD_CONST 4 ((1, 2, 3)) # - - - [(1, 2, 3)]
3 UNPACK_SEQUENCE 3 # - - - [1, 2, 3]
6 STORE_FAST 0 (a) # 1 - - [2, 3]
9 STORE_FAST 1 (b) # 1 2 - [3]
12 STORE_FAST 2 (c) # 1 2 3 []
5 15 LOAD_FAST 2 (c) # 1 2 3 [3]
18 LOAD_FAST 1 (b) # 1 2 3 [3, 2]
21 LOAD_FAST 0 (a) # 1 2 3 [3, 2, 1]
24 BUILD_TUPLE 3 # 1 2 3 [(3, 2, 1)]
27 DUP_TOP # 1 2 3 [(3, 2, 1), (3, 2, 1)]
28 UNPACK_SEQUENCE 3 # 1 2 3 [3, 2, 1, (3, 2, 1)]
31 STORE_FAST 0 (a) # 3 2 3 [2, 1, (3, 2, 1)]
34 STORE_FAST 1 (b) # 3 2 3 [1, (3, 2, 1)]
37 STORE_FAST 2 (c) # 3 2 1 [(3, 2, 1)]
40 DUP_TOP # 3 2 1 [(3, 2, 1), (3, 2, 1)]
41 UNPACK_SEQUENCE 3 # 3 2 1 [3, 2, 1, (3, 2, 1)]
44 STORE_FAST 2 (c) # 3 2 3 [2, 1, (3, 2, 1)]
47 STORE_FAST 0 (a) # 2 2 3 [1, (3, 2, 1)]
50 STORE_FAST 1 (b) # 2 1 3 [(3, 2, 1)]
53 UNPACK_SEQUENCE 3 # 2 1 3 [3, 2, 1]
56 STORE_FAST 1 (b) # 2 3 3 [2, 1]
59 STORE_FAST 0 (a) # 2 3 3 [1]
62 STORE_FAST 2 (c) # 2 3 1 []