请教各位大佬一个 Python 问题,关于局部变量。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
jurassic2long
V2EX    Python

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

  •  
  •   jurassic2long 2023-03-20 22:29:12 +08:00 2314 次点击
    这是一个创建于 1010 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    11 条回复    2023-03-21 12:55:05 +08:00
    f1ush
        1
    f1ush  
       2023-03-20 22:45:23 +08:00   1
    https://imgur.com/a/vYwLyHl
    看了一下 Python 字节码,可以看到 aa 和 bb 都是编译成了全局变量了,cc 编译出来是局部变量;
    个人猜测:Python 看到没有出现过的变量名会先去全局找,但是看到 += 符号的时候回默认前面的变量是已经出现过的本地变量
    hsfzxjy
        2
    hsfzxjy  
       2023-03-20 22:47:25 +08:00 via Android
    这种情况下,加一句 global a 或 nonlocal a
    wynemo
        3
    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 mean 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
        4
    llsquaer  
       2023-03-20 23:03:28 +08:00
    a 是列表 容器可变类型 , 内存地址指向没有变.所以可以在函数内部修改..如果你把 a 改为 字符串..就改不了.

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

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

    写全就是 a= 1 + a

    这个问题是 函数局部变量 a 还没有赋值, 函数内部是优先内部变量处理. a= 这个时候可以理解为暂存的变量,没有值,还没划分内存地址. =号后面才是真正的值.. 后面的 +a 加的是局部变量 a , 所以报错.. 因为你 + 的是还没值的自己..
    iOCZ
        5
    iOCZ  
       2023-03-20 23:14:48 +08:00
    引用 a 是全局的,但是赋值 a 的话,得加 global
    AV1
        6
    AV1  
       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
        7
    mylifcc  
       2023-03-21 00:21:42 +08:00   1
    list 的加法 要用 a[:] += [3],如果使用 a += [3] 这种语法,则会创建一个新的列表对象,并将其赋值给 a 变量,而不是修改原始列表。
    zzl22100048
        9
    zzl22100048  
       2023-03-21 08:25:33 +08:00   1
    @mylifcc 不对吧,list += 会调用 __iadd__ 后做一个赋值,内部实际执行的是 extend 方法 并返回 self ,并没有创建新的列表对象。

    他这里用+= 对变量赋值了,导致函数内部会将 a 解析为局部变量
    aijam
        10
    aijam  
       2023-03-21 12:48:10 +08:00   1
    lovelylain
        11
    lovelylain  
       2023-03-21 12:55:05 +08:00 via Android   1
    a += x 相当于 a = a.__iadd__(x),对变量 a 重新赋值了,所以在没有 global 或 nonlocal 显式声明时被当做 local 变量,不过感觉这个不是很合理呀,因为 python 未定义变量是没法+=的,肯定是有在前面有=或者 import 赋值才行,既然这样+=就不应该作为变量是否本地的依据。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3209 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 11:07 PVG 19:07 LAX 03:07 JFK 06:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86