关于 Python 的一个问题

2016-07-25 15:15:24 +08:00
 strahe

早上补习黑魔法的时候,在知乎上看到一个问题:

>>> a = (1, [1,2,3], 'a')
>>> a[1] += [4]
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> a
(1, [1, 2, 3, 4], 'a')
>>>

没搞明白这是为什么,来个明白人解释一下。

4056 次点击
所在节点    Python
30 条回复
jixiangqd
2016-07-25 20:21:28 +08:00
@zxc111 学习了!
21grams
2016-07-25 20:22:45 +08:00
妥妥的就是个 bug ,要么就别报错,要报错就别修改值
prm
2016-07-25 23:03:36 +08:00
并不是一个 Bug ,来看一下 byte code

$ py -3
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from dis import dis
>>> dis('''
... a = (1, [1,2,3], 'a')
... a[1] += [4]
... ''')
2 0 LOAD_CONST 0 (1)
3 LOAD_CONST 0 (1)
6 LOAD_CONST 1 (2)
9 LOAD_CONST 2 (3)
12 BUILD_LIST 3
15 LOAD_CONST 3 ('a')
18 BUILD_TUPLE 3
21 STORE_NAME 0 (a)

3 24 LOAD_NAME 0 (a)
27 LOAD_CONST 0 (1)
30 DUP_TOP_TWO
31 BINARY_SUBSCR
32 LOAD_CONST 4 (4)
35 BUILD_LIST 1
38 INPLACE_ADD
39 ROT_THREE
40 STORE_SUBSCR
41 LOAD_CONST 5 (None)
44 RETURN_VALUE

a[1] += [4]实际是两部操作,+= 和 []=

INPLACE_ADD 是 +=
STORE_SUBSCR 是 []=

先发生了+=,然后 []= 报错了。仅此而已。
prm
2016-07-25 23:08:01 +08:00
归根结底这是 Python 语言设计的锅, python 定义了与各种 operator 等价的 magic method (双下划线 method ,比如__iadd__是+=,当然,也就是后来编译出来的 INPLACE_ADD),当你从语法上玩弄语义的时候(+=, []= 合并成了 x[y]+=z ),就被自己玩了。。
fzinfz
2016-07-26 01:23:53 +08:00
为什么都在关心 += 。。。

a = (1,2)
a[1] = 2

同样的报错

Tuples are immutable.
Ahri
2016-07-26 04:33:40 +08:00
@prm 是对的。

说原因是 tuples are immutable 的没看懂这个问题。

建议类似操作用 append 或 extend ,不报错。

>>> a=(1,[2])
>>> a[1]
[2]
>>> a[1].append(2)
>>> a
(1, [2, 2])
fzinfz
2016-07-26 08:27:04 +08:00
@fzinfz 我错了,确实要关心+=,之前没看懂问题(>﹏<)
sudoz
2016-07-26 09:55:24 +08:00
@dosin tuple 里所引用的对象不可变,但是对象的值可变
jixiangqd
2016-07-26 11:08:50 +08:00
突然想明白了为啥+= 要有个[]=的操作。
为了实现 a = [1];a[0]+=1 这种基本类型在容器内执行执行+=
wizardoz
2016-07-26 13:21:57 +08:00
赶紧去提 bug

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/294777

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX