gpt4 book ai didi

python - 在 Python 中写入(而不是)全局变量

转载 作者:太空狗 更新时间:2023-10-30 00:56:14 25 4
gpt4 key购买 nike

来自不太动态的 C++,我在理解这段 Python (2.7) 代码的行为时遇到了一些困难。

注意:我知道这是糟糕的编程风格/邪恶的,但我还是想理解它。

vals = [1,2,3]

def f():
vals[0] = 5
print 'inside', vals

print 'outside', vals
f()
print 'outside', vals

此代码运行无误,f 操纵(看似)全局列表。这与我之前的理解相反,即要在函数中操作(而不仅仅是读取)的全局变量必须声明为 global ...

另一方面,如果我将 vals[0] = 5 替换为 vals += [5,6],执行将失败并出现 UnboundLocalError 除非我将 global vals 添加到 f。这也是我预计在第一种情况下会发生的情况。

您能解释一下这种行为吗?

为什么我可以在第一种情况下操作vals?为什么第二种操作会失败而第一种不会?

更新:在评论中指出 vals.extend(...) 无需 global 即可工作。这让我更加困惑 - 为什么 += 与调用 extend 的方式不同?

最佳答案

global 仅在您尝试更改变量引用的对象时才需要。因为 vals[0] = 5 更改了实际对象而不是引用,所以不会引发错误。但是,对于 vals += [5, 6],解释器会尝试查找局部变量,因为它无法更改全局变量。

令人困惑的是,对列表使用+= 运算符会修改原始列表,如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)
1 0 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)
1 0 LOAD_FAST 0 (v)
3 LOAD_CONST 1 (1)
6 BUILD_LIST 1
9 INPLACE_ADD
10 STORE_FAST 0 (v)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
d
>>> dis.dis(c)
1 0 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

我们可以看到函数 ac 使用 LOAD_GLOBAL,而 b 尝试使用 LOAD_FAST。我们现在可以看到为什么使用 += 不起作用 - 解释器尝试将 v 作为局部变量加载,因为它是就地添加的默认行为。因为它不知道 v 是否是一个列表,所以它基本上假定该行与 v = v + [1] 的含义相同。

关于python - 在 Python 中写入(而不是)全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20771487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com