You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中不使用全局变量与返回值,如何使父函数变量被子函数赋值后生效?

Python中不使用全局变量与返回值,如何使父函数变量被子函数赋值后生效?

嘿,这个问题在Python嵌套函数结合GUI回调的场景里挺常见的~咱们先拆解下你代码里的问题:你在subfunction里写的var = 22,其实是创建了一个属于subfunction自己的局部变量,和外层function里定义的var完全是两个独立的东西,所以外层的var始终是99,最后打印出来自然不是你想要的22。

这里给你两种不用全局变量、也不用返回值的解决方法:

方法一:使用nonlocal关键字(Python 3+适用)

nonlocal是Python 3专门为嵌套函数设计的关键字,它可以告诉Python:当前函数里的这个变量,不是自己的局部变量,而是来自上一层嵌套函数的局部变量。这样赋值时就会直接修改外层的变量,而不是新建一个。

修改后的代码如下:

import tkinter as tk
def function():
    def subfunction():
        nonlocal var  # 声明该变量来自外层function的局部作用域
        var = 22
        print('subfunction', var)
        top.destroy()
    var = 99
    top = tk.Toplevel(root)
    top.title('top level')
    tk.Button(top, text='Button toplevel', command=subfunction).pack()
    root.wait_window(top)
    print('function', var)  # 现在会输出22啦
var = 0
root = tk.Tk()
print(var)
tk.Button(root, text='Button', command=function).pack()
root.mainloop()

方法二:用可变对象包装变量(兼容Python 2和3)

如果需要兼容Python 2,或者不想用nonlocal关键字,可以用可变对象(比如列表、字典)来包装你的变量。因为可变对象的内容修改后,引用它的地方都会看到变化,不需要额外关键字。

比如用列表包装var

import tkinter as tk
def function():
    var = [99]  # 把变量放进列表里
    def subfunction():
        var[0] = 22  # 修改列表的第一个元素
        print('subfunction', var[0])
        top.destroy()
    top = tk.Toplevel(root)
    top.title('top level')
    tk.Button(top, text='Button toplevel', command=subfunction).pack()
    root.wait_window(top)
    print('function', var[0])  # 这里会输出22
var = 0
root = tk.Tk()
print(var)
tk.Button(root, text='Button', command=function).pack()
root.mainloop()

这两种方法都能满足你的需求:不用全局变量,也不用返回值,就能让function里的var变成subfunction里赋值的22。其中nonlocal更直观,适合Python 3+环境;列表包装法则兼容性更强。

备注:内容来源于stack exchange,提问作者user28976168

火山引擎 最新活动