您始终可以修改元组内的可变值.你看到的令人费解的行为
>>> thing[0] += 'd'
是由=引起的. =运算符执行就地添加但也执行赋值 – 就地添加仅用于文件,但由于元组是不可变的,因此赋值失败.想一想就好
>>> thing[0] = thing[0] + 'd'
更好地解释了这个我们可以使用标准库中的dis module来查看从两个表达式生成的字节码.使用=我们得到一个INPLACE_ADD字节码:
>>> def f(some_list):
... some_list += ["foo"]
...
>>> dis.dis(f)
2 0 LOAD_FAST 0 (some_list)
3 LOAD_CONST 1 ('foo')
6 BUILD_LIST 1
9 INPLACE_ADD
10 STORE_FAST 0 (some_list)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
我们得到一个BINARY_ADD:
>>> def g(some_list):
... some_list = some_list + ["foo"]
>>> dis.dis(g)
2 0 LOAD_FAST 0 (some_list)
3 LOAD_CONST 1 ('foo')
6 BUILD_LIST 1
9 BINARY_ADD
10 STORE_FAST 0 (some_list)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
请注意,我们在两个地方都获得了STORE_FAST.这是当你尝试存储回元组时失败的字节码 – 在工作正常之前出现的INPLACE_ADD.
这就解释了为什么“不工作,无效”的情况会使修改后的列表落后:元组已经有了对列表的引用:
>>> id(thing[0])
3074072428L
然后INPLACE_ADD修改该列表,STORE_FAST失败:
>>> thing[0] += 'd'
Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment
因此元组仍然具有对同一列表的引用,但列表已就地修改:
>>> id(thing[0])
3074072428L
>>> thing[0]
['b', 'c', 'd']