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
zictos
V2EX    Python

Python 某个函数内有多个函数嵌套,主函数里的变量能被内部的其他函数像全局变量一样使用吗?

  •  
  •   zictos 2023-01-31 11:04:31 +08:00 2297 次点击
    这是一个创建于 1065 天前的主题,其中的信息可能已经有所发展或是发生改变。

    试了下,是可以正常访问的,但是无法在内部的其他函数中去修改这个外面的主函数的变量, 有没有办法能修改呢?

    def func1(): def func2(): print(a) #输出是 2 a = 2 func2() a = 1 func1() 
    17 条回复    2023-01-31 18:56:00 +08:00
    723X
        1
    723X  
       2023-01-31 11:10:08 +08:00 via Android
    定义时加 global 声明全局变量
    PEax
        2
    PEax  
       2023-01-31 11:11:56 +08:00
    global a
    zictos
        3
    zictos  
    OP
       2023-01-31 11:12:26 +08:00
    @723X #1 不行的,在 func2 中加 global ,那么 a 的值就等于 1 了,修改 a 后也是修改了最外面的那个 a ,不能修改 func1 函数中的那个 a
    zictos
        4
    zictos  
    OP
       2023-01-31 11:12:56 +08:00
    @PEax #2 我是想在 func2 中修改 func1 中的那个 a
    VYSE
        5
    VYSE  
       2023-01-31 11:14:15 +08:00
    @zictos #3 初始化:a = [2]; 读写 a[0]
    SimbaPeng
        6
    SimbaPeng  
       2023-01-31 11:14:57 +08:00   2
    nonlocal a
    julyclyde
        7
    julyclyde  
       2023-01-31 11:15:48 +08:00
    好像是著名的 2/3 坑啊?
    nonlocal 在 python3 才开始有的
    zictos
        8
    zictos  
    OP
       2023-01-31 11:19:59 +08:00
    @SimbaPeng #6 感谢,这个可以使用,能成功在 func2 中修改 func1 中的 a
    Kirscheis
        9
    Kirscheis  
       2023-01-31 11:25:48 +08:00 via Android   1
    在 func2 里加一行

    nonlocal a

    但这么搞有糊屎山的嫌疑,尽量少用
    fzls
        10
    fzls  
       2023-01-31 11:26:02 +08:00
    子函数里面访问外面的变量是值捕获的,所以想要在里面修改外部主函数里的变量值,只能通过一个引用类型来作为中转,比如 dict 或者 class

    class Wrapper(): pass

    def func1():
    def func2():
    print(a) # 输出是 2

    a = 2
    wrapper_class.a = 2
    wrapper_dict["a"] = 2

    print("before func2", a, wrapper_class.a, wrapper_dict["a"])
    func2()
    print("after func2", a, wrapper_class.a, wrapper_dict["a"])


    a = 1

    # 使用一个 class 来保存变量
    wrapper_class = Wrapper()
    wrapper_class.a = 1

    # 使用一个 dict 来保存
    wrapper_dict = {}
    wrapper_dict["a"] = 1

    print("before func1", a, wrapper_class.a, wrapper_dict["a"])
    func1()
    print("after func1", a, wrapper_class.a, wrapper_dict["a"])
    fzls
        11
    fzls  
       2023-01-31 11:27:40 +08:00
    或者像前面一样,用个 list 包一下,总之就是要用一个引用类型来保证值传递过去仍是同一个变量,从而完成修改
    xuyang2
        12
    xuyang2  
       2023-01-31 13:34:09 +08:00
    谷歌搜索:
    python scope LEGB
    NoOneNoBody
        15
    NoOneNoBody  
       2023-01-31 13:41:22 +08:00
    按闭包定义域,无定义就读取上一层中的定义,想比较稳妥不出错,就逐层传参数
    def fun1(a) / def fun2(a) 这样传过去
    godall
        16
    godall  
       2023-01-31 14:39:54 +08:00
    楼主,函数嵌套函数的用途就不是这个场景,嵌套函数要么原子性非常强,不会共享外部变量(需要的变量直接参数传递)。要共享的话,当然定义成类方式了。
    zictos
        17
    zictos  
    OP
       2023-01-31 18:56:00 +08:00
    @godall #16 本身也是平时写着玩的,不是什么很重要的代码。有时候本身一个文件的主代码有用到全局变量,想用函数把全部打码包起来又懒得改变任何其他代码,那么就只能用这种方式了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4882 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 41ms UTC 03:48 PVG 11:48 LAX 19:48 JFK 22:48
    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