首先一起来看一段代码:

"""
global修改的是全局变量
nonlocal修改的是闭包外部函数局部变量
"""
# 定义全局变量:作用域覆盖整个程序
num1 = 100

# 定义闭包的外部函数
def outer():
    # 外部函数的局部变量:仅作用于outer()内部
    num2 = 200

    # 嵌套的内部函数(闭包核心)
    def inner():
        # global关键字:声明接下来要修改的num1是全局变量
        global num1
        num1 = 1000  # 修改全局变量num1的值

        # nonlocal关键字:声明接下来要修改的num2是外部函数outer()的局部变量
        nonlocal num2
        num2 = 2000  # 修改外部函数的局部变量num2的值

        # 内部函数自身的局部变量:仅作用于inner()内部
        num3 = 300
        num3 = 3000  # 自身局部变量直接修改,无需关键字
        print(f"内部函数局部变量num3:{num3}")

    # 调用内部函数:触发inner()的执行逻辑
    inner()
    print(f"外部函数局部变量num2:{num2}")  # 打印被inner()修改后的num2
    # 返回内部函数地址(闭包特性,此处未用到)
    return inner

# 调用外部函数:执行outer()的逻辑
outer()
# 打印被inner()修改后的全局变量num1
print(f"全局变量num1:{num1}")
内部函数局部变量num3:3000
外部函数局部变量num2:2000
全局变量num1:1000

这段 Python 代码核心是演示global和nonlocal关键字的使用场景,清晰区分了不同作用域变量的修改规则,我会帮你拆解代码逻辑和执行结果:

1. 代码整体功能总结

这段代码通过「全局变量 + 闭包(外部函数 + 内部函数)」的结构,分别展示了:

  • global关键字:在函数内部修改全局变量的方法;
  • nonlocal关键字:在闭包的内部函数中修改外部函数局部变量的方法;
  • 普通局部变量:函数自身的局部变量可直接修改,无需额外关键字。

作为编程新手,我会用最通俗的大白话 + 生活化例子帮你拆解这段代码,核心搞懂「变量的 “地盘”(作用域)」和「怎么修改不同地盘的变量」,全程不绕专业术语~

先明确核心概念:变量的 “地盘”(作用域)

可以把变量想象成 “不同房间的物品”:

  • 全局变量:放在家里「客厅」的物品,整个房子(整个 Python 文件)里的人(所有函数)都能碰;
  • 外部函数局部变量:放在「父母卧室」的物品,只有父母(外部函数)和你(内部函数)能碰;
  • 内部函数局部变量:放在「你自己卧室」的物品,只有你自己(内部函数)能碰。

修改不同 “房间” 的物品,规则不一样:

  • 改自己卧室的物品:直接拿(直接赋值);
  • 改父母卧室的物品:要先喊一声 “这是爸妈的东西,我要改啦”(用nonlocal声明);
  • 改客厅的物品:要先喊一声 “这是全家的东西,我要改啦”(用global声明)。
# 1. 定义全局变量(客厅的物品):num1=100,整个文件都能访问
num1 = 100

# 2. 定义外部函数outer(相当于“父母的房间”)
def outer():
    # 3. 外部函数的局部变量(父母卧室的物品):num2=200,只有outer里能用
    num2 = 200

    # 4. 内部函数inner(相当于“你的房间”,嵌套在父母房间里)
    def inner():
        # 5. 声明:接下来要改的num1是“客厅的全局变量”(先喊一声)
        global num1
        # 6. 修改全局变量num1:把客厅的num1从100改成1000
        num1 = 1000

        # 7. 声明:接下来要改的num2是“父母卧室的变量”(先喊一声)
        nonlocal num2
        # 8. 修改外部函数的变量num2:把父母卧室的num2从200改成2000
        num2 = 2000

        # 9. 内部函数的局部变量(你自己卧室的物品):num3=300
        num3 = 300
        # 10. 改自己的变量:直接改,不用喊(因为是自己的东西)
        num3 = 3000
        # 11. 打印自己卧室的num3,结果是3000
        print(f"内部函数局部变量num3:{num3}")

    # 12. 调用内部函数inner:相当于“走进你的房间,执行里面的操作”
    inner()
    # 13. 打印父母卧室的num2(已经被你改成2000了)
    print(f"外部函数局部变量num2:{num2}")
    # 14. 返回inner函数(新手暂时不用管这行,只是闭包的小特性,不影响核心逻辑)
    return inner

# 15. 调用外部函数outer:相当于“走进父母房间,执行里面的操作”
outer()
# 16. 打印客厅的num1(已经被你改成1000了)
print(f"全局变量num1:{num1}")

代码执行过程(像 “过电影” 一样)

  1. 先给客厅放个num1=100,父母卧室放个num2=200;
  2. 执行outer(),走进父母卧室,又执行inner()走进你的卧室;
  3. 你在自己卧室里:
    • 喊 “要改客厅的 num1”,把num1改成 1000;
    • 喊 “要改爸妈卧室的 num2”,把num2改成 2000;
    • 把自己卧室的num3从 300 改成 3000,打印出来(显示 3000);
  4. 走出你的卧室,回到父母卧室,打印num2(显示 2000);
  5. 走出父母卧室,回到客厅,打印num1(显示 1000)。
内部函数局部变量num3:3000
外部函数局部变量num2:2000
全局变量num1:1000

新手必记总结

  1. 改自己函数里的变量:直接赋值(比如num3=3000),不用加任何关键字;
  2. 改全局变量:先写global 变量名,再赋值(比如global num1后改num1);
  3. 改外层函数的变量(函数套函数时):先写nonlocal 变量名,再赋值(比如nonlocal num2后改num2)。

这三个规则是 Python 里修改不同 “地盘” 变量的核心,记住就不会乱啦~

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐