为什么Python在有';这已经是现成的了吗?

为什么Python在有';这已经是现成的了吗?,python,python-internals,Python,Python Internals,如果您反汇编以下函数 def test(): t = (1, 2, [30]) t[2] += [40] return t 您将看到t[2]+=[40]对应的字节码如下所示: 3 18 LOAD_FAST 0 (t) 21 LOAD_CONST 2 (2) 24 DUP_TOPX 2

如果您反汇编以下函数

def test():
    t = (1, 2, [30])
    t[2] += [40]
    return t
您将看到
t[2]+=[40]
对应的字节码如下所示:

  3          18 LOAD_FAST                0 (t)
             21 LOAD_CONST               2 (2)
             24 DUP_TOPX                 2
             27 BINARY_SUBSCR
             28 LOAD_CONST               4 (40)
             31 BUILD_LIST               1
             34 INPLACE_ADD
             35 ROT_THREE
             36 STORE_SUBSCR
temp = t[2]
temp += [40] # INPLACE_ADD
t[2] = temp  # STORE_SUBSCR

[40]
被连接到存储在
t[2]
中的列表,在
INPLACE\u ADD
之后,Python为什么决定添加
STORE\u SUBSCR

  3          18 LOAD_FAST                0 (t)
             21 LOAD_CONST               2 (2)
             24 DUP_TOPX                 2
             27 BINARY_SUBSCR
             28 LOAD_CONST               4 (40)
             31 BUILD_LIST               1
             34 INPLACE_ADD
             35 ROT_THREE
             36 STORE_SUBSCR
temp = t[2]
temp += [40] # INPLACE_ADD
t[2] = temp  # STORE_SUBSCR
Python实际上并不就地更新列表,而是先将值存储在一个临时变量中

证明:

>>> lst  = [[1], [2], [3]]
>>> def func():
...     lst[0] = [100]
...     return [40]
...
>>> lst[0] += func()
>>> lst
[[1, 40], [2], [3]]  # Not [[100, 40], [2], [3]]

这是因为
t[2]+=[40]
的工作原理如下:

  3          18 LOAD_FAST                0 (t)
             21 LOAD_CONST               2 (2)
             24 DUP_TOPX                 2
             27 BINARY_SUBSCR
             28 LOAD_CONST               4 (40)
             31 BUILD_LIST               1
             34 INPLACE_ADD
             35 ROT_THREE
             36 STORE_SUBSCR
temp = t[2]
temp += [40] # INPLACE_ADD
t[2] = temp  # STORE_SUBSCR
Python实际上并不就地更新列表,而是先将值存储在一个临时变量中

证明:

>>> lst  = [[1], [2], [3]]
>>> def func():
...     lst[0] = [100]
...     return [40]
...
>>> lst[0] += func()
>>> lst
[[1, 40], [2], [3]]  # Not [[100, 40], [2], [3]]

这是因为
INPLACE\u ADD
仅要求在可能的情况下就地完成操作;如果对象是不可变的,或者没有费心实现
\uu iadd\uuuu
就地添加
会回到常规的、非就地添加。如果代码是

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

显然有必要将新元组存储回
t[2]
,因为该操作会生成一个新元组,而不是对旧元组进行变异。

这是因为
INPLACE\u ADD
仅要求在可能的情况下就地执行该操作;如果对象是不可变的,或者没有费心实现
\uu iadd\uuuu
就地添加
会回到常规的、非就地添加。如果代码是

t = [1, 2, (30)]
t[2] += (40,)
显然有必要将新元组存储回
t[2]
,因为该操作会生成一个新元组,而不是对旧元组进行变异