请教各位大佬一个 Python 问题,关于局部变量。

2023-03-20 22:29:12 +08:00
 jurassic2long

如图,第三个函数中,全局变量 a 为何被当做局部变量了,与前两个函数有什么不一样?
(第一次发图不知道能不能显示出来,多写一种格式试试)
https://imgur.com/SJzAH2m

1850 次点击
所在节点    Python
11 条回复
f1ush
2023-03-20 22:45:23 +08:00
https://imgur.com/a/vYwLyHl
看了一下 Python 字节码,可以看到 aa 和 bb 都是编译成了全局变量了,cc 编译出来是局部变量;
个人猜测:Python 看到没有出现过的变量名会先去全局找,但是看到 += 符号的时候回默认前面的变量是已经出现过的本地变量
hsfzxjy
2023-03-20 22:47:25 +08:00
这种情况下,加一句 global a 或 nonlocal a
wynemo
2023-03-20 22:47:52 +08:00
>>> a = 5
>>> id(a)
4349762296
>>> a += 6
>>> id(a)
4349762488

因为生成新的对象了吧

The global statement is a declaration which holds for the entire current code block. It means that the listed identifiers are to be interpreted as globals. It would be impossible to assign to a global variable without global, although free variables may refer to globals without being declared global.
llsquaer
2023-03-20 23:03:28 +08:00
a 是列表 容器可变类型 , 内存地址指向没有变.所以可以在函数内部修改..如果你把 a 改为 字符串..就改不了.

基础问题. 你需要先了解 可变类型 和 不可变类型的区别.

最后一个函数是 += 是累加赋值的意思. 列表确实是可以用+号扩展的.

写全就是 a= 1 + a

这个问题是 函数局部变量 a 还没有赋值, 函数内部是优先内部变量处理. a= 这个时候可以理解为暂存的变量,没有值,还没划分内存地址. =号后面才是真正的值.. 后面的 +a 加的是局部变量 a , 所以报错.. 因为你 + 的是还没值的自己..
iOCZ
2023-03-20 23:14:48 +08:00
引用 a 是全局的,但是赋值 a 的话,得加 global
DOLLOR
2023-03-20 23:18:33 +08:00
这就是个陷阱。
+=跟=一样,都会声明新的本地变量,所以第三个函数里的 a 其实是局部变量,而非外部的 a 。

再一个更简单的例子:
a = 1

def f1():
𰻝# 报错,此处的 a 不是外部的 a
𰻝a += 1

f1()

回避方式:
a = 1
def f1():
𰻝global a
𰻝a += 1

f1()
print(a)
mylifcc
2023-03-21 00:21:42 +08:00
list 的加法 要用 a[:] += [3],如果使用 a += [3] 这种语法,则会创建一个新的列表对象,并将其赋值给 a 变量,而不是修改原始列表。
mylifcc
2023-03-21 01:01:35 +08:00
zzl22100048
2023-03-21 08:25:33 +08:00
@mylifcc 不对吧,list += 会调用 __iadd__ 后做一个赋值,内部实际执行的是 extend 方法 并返回 self ,并没有创建新的列表对象。

他这里用+= 对变量赋值了,导致函数内部会将 a 解析为局部变量
aijam
2023-03-21 12:48:10 +08:00
lovelylain
2023-03-21 12:55:05 +08:00
a += x 相当于 a = a.__iadd__(x),对变量 a 重新赋值了,所以在没有 global 或 nonlocal 显式声明时被当做 local 变量,不过感觉这个不是很合理呀,因为 python 未定义变量是没法+=的,肯定是有在前面有=或者 import 赋值才行,既然这样+=就不应该作为变量是否本地的依据。

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

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

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

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

© 2021 V2EX