如何理解下面这串python代码和它的运行结果呢?

a, b = 0, 1
a, b = b, a+b

这串代码的运行结果:a=1,b=1。为了进一步理解在python内部发生了什么,引入dis库分析该代码的汇编语句。

import dis
def func():
    a, b = 0, 1
    a, b = b, a+b
 dis.dis(func)

运行结果如下:

  9           0 LOAD_CONST               3 ((0, 1))
              2 UNPACK_SEQUENCE          2
              4 STORE_FAST               0 (a)
              6 STORE_FAST               1 (b)

 10           8 LOAD_FAST                1 (b)
             10 LOAD_FAST                0 (a)
             12 LOAD_FAST                1 (b)
             14 BINARY_ADD
             16 ROT_TWO
             18 STORE_FAST               0 (a)
             20 STORE_FAST               1 (b)
             22 LOAD_CONST               0 (None)
             24 RETURN_VALUE

上面的汇编语句中,STORE_*代表存入堆栈,LOAD_*代表读出堆栈。ROT_TWO代表交换堆栈最后两位。因此从结论出发,在python中,赋值语句的右边表达式是最先被运算的,并且运算结果都会暂存到堆栈中,而不受python的指针影响;在右边运算结束后,才会进行左边表达式的运算,不同于右边表达式,它是按照从左到右实时执行赋值语句的。举个例子,这个例子来源于知乎用户@南葱的专栏Python在unpacking上的一个小陷阱中所写。

j = 0, m = [1, 3, 5] 
j, m[j] = m[j], 99

print(j)    # 1
print(m)    # [1, 99, 5]

首先进行右边的运算,jm[j]的运算结果为1和99;接着进行左边的运算,由于是实时的,因此先算出来j的值为1,再计算m[j]时即变为m[1],最后的运算就变成m[1] = 99,将m数组第二位赋值99.得到了最后的结果。