global仅在尝试更改变量引用的对象时才需要。因为
vals[0] = 5更改的是实际对象而不是参考,所以不会引发任何错误。但是,使用
vals+= [5, 6],解释器会尝试查找局部变量,因为它无法更改全局变量。
令人困惑的是,将
+=运算符与list一起使用会修改原始列表,例如
vals[0] = 5。虽然
vals += [5,6]失败了,但
vals.extend([5,6])行得通。我们可以争取到的帮助为
dis.dis我们提供一些线索。
>>> def a(): v[0] = 1>>> def b(): v += [1]>>> def c(): v.extend([1])>>> import dis>>> dis.dis(a) 10 LOAD_ConST 1 (1) 3 LOAD_GLOBAL 0 (v) 6 LOAD_ConST 2 (0) 9 STORE_SUBSCR 10 LOAD_ConST 0 (None) 13 RETURN_VALUE >>> dis.dis(b) 10 LOAD_FAST 0 (v) 3 LOAD_ConST 1 (1) 6 BUILD_LIST 1 9 INPLACE_ADD10 STORE_FAST 0 (v) 13 LOAD_ConST 0 (None) 16 RETURN_VALUE d>>> dis.dis(c) 10 LOAD_GLOBAL 0 (v) 3 LOAD_ATTR 1 (extend) 6 LOAD_ConST 1 (1) 9 BUILD_LIST 1 12 CALL_FUNCTION 1 15 POP_TOP 16 LOAD_ConST 0 (None) 19 RETURN_VALUE
我们可以看到功能
a和
c用途
LOAD_GLOBAL,而
b尝试使用
LOAD_FAST。现在我们可以看到为什么使用
+=不起作用的原因-
解释器尝试将其
v作为局部变量加载,因为它是就地添加的默认行为。由于它不知道是否
v为列表,因此基本上假设该行的含义与相同
v = v + [1]。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)