欢迎光临
我们一直在努力

第13课:Python|局部变量|全局变量|函数作用域与闭包基础精讲

在这里插入图片描述

文章目录

  • 📖 开篇导读
  • 🎯 学习目标
  • 📚 知识点理论精讲
    • 一、作用域(Scope)的基本概念
    • 二、局部变量(Local Variable)
      • 局部变量的生命周期
    • 三、全局变量(Global Variable)
      • 3.1 读取全局变量
      • 3.2 修改全局变量:`global`关键字
      • 3.3 何时使用全局变量
    • 四、LEGB规则详解
      • 4.1 各层级示例
      • 4.2 屏蔽效应
      • 4.3 内置作用域示例
    • 五、嵌套函数与`nonlocal`关键字
      • 5.1 访问外层变量(只读)
      • 5.2 修改外层变量:`nonlocal`
      • 5.3 多层嵌套
    • 六、闭包(Closure)基础
      • 6.1 闭包的形成条件
      • 6.2 闭包的作用
      • 6.3 查看闭包中的变量
      • 6.4 常见误区:循环中创建闭包
    • 七、作用域与变量生存周期
  • 💻 代码案例实操
    • 案例1:局部变量与全局变量基础演示
    • 案例2:LEGB规则完整演示
    • 案例3:`nonlocal`深入理解
    • 案例4:闭包实现计数器
    • 案例5:闭包实现简单的缓存(记忆化)
    • 案例6:循环闭包陷阱及解决
    • 案例7:实际工作场景——配置管理
  • ⚠️ 易错点避坑总结
  • 📝 课后实战练习题
      • 第1题:全局与局部变量分析
      • 第2题:正确使用`global`
      • 第3题:嵌套函数与`nonlocal`
      • 第4题:闭包实现简单的平均值计算器
      • 第5题:循环闭包陷阱修复
      • 第6题:LEGB查找顺序验证
      • 第7题:综合应用——带重置功能的计数器
  • 🧠 知识点思维导图总结
  • 🔜 下节课预告
    • 第14课:高阶函数、lambda匿名函数、map/filter/sorted内置高阶函数实战
  • 🔗《50节课 Python 从入门到精通》系列课程导航

📖 开篇导读

前面两节课我们学习了函数的定义、参数传递的各种花样。但你有没有想过:函数内部定义的变量,在函数外面能访问吗?不同函数之间的变量会互相影响吗?为什么有些变量在函数内部修改后,外面的值却没有变化?这些问题的答案,都藏在作用域这个概念中。

作用域(Scope)就是变量的“可见范围”。理解作用域,你才能写出预期正确的代码,避免“明明改了变量却没变”的诡异bug。此外,闭包(Closure) 是作用域概念的延伸,也是装饰器、函数式编程的基础,面试中经常出现。

💡 工作场景:当你需要在一个函数中记住某些状态(比如计数器、缓存),但又不想用全局变量时,闭包就是最佳解决方案。很多框架和库的内部实现都大量使用了闭包。

本课我们将深入讲解:

  • 局部变量与全局变量的区别及使用
  • global和nonlocal关键字的作用
  • LEGB作用域查找规则
  • 闭包的概念与简单应用

学完本课,你将能够精准控制变量的作用范围,写出更安全、更模块化的代码。


🎯 学习目标

目标编号具体掌握内容对应面试/工作价值
1️⃣ 理解局部变量和全局变量的区别 避免命名冲突,写出清晰代码
2️⃣ 掌握global关键字在函数内修改全局变量 必要情况下修改全局状态
3️⃣ 理解LEGB规则(Local, Enclosing, Global, Built-in) 面试高频,排查变量查找问题
4️⃣ 掌握nonlocal关键字修改嵌套函数中的外层变量 闭包进阶必备
5️⃣ 理解闭包的概念、形成条件及应用场景 装饰器基础,面试常考

🔥 面试考点:“Python中变量的作用域有哪些?”“global和nonlocal的区别?”“什么是闭包?闭包有什么好处?”“LEGB顺序是什么?”


📚 知识点理论精讲

一、作用域(Scope)的基本概念

作用域是指变量在程序中可以被访问的范围。Python的作用域是静态的(由代码位置决定),但在运行时动态查找。

Python有四种作用域,按查找顺序(LEGB):

  • L – Local:函数内部(局部作用域)
  • E – Enclosing:嵌套函数的外层函数作用域
  • G – Global:模块全局作用域
  • B – Built-in:内置作用域(如print、len)
  • 🧠 通俗类比:作用域就像你的居住区域。局部变量就像你家里的物品(只有你家人能直接使用);全局变量就像城市公共设施(所有人都能访问);内置函数就像国家的基础设施(全国通用)。如果你要找一样东西,先从家里找(Local),再到小区(Enclosing),再到城市(Global),最后到国家(Built-in)。


    二、局部变量(Local Variable)

    在函数内部赋值的变量,作用域仅限于该函数。

    def my_func():
    x = 10 # 局部变量
    print(x)

    my_func()
    print(x) # NameError: name 'x' is not defined

    特点:

    • 函数执行时创建,函数返回时销毁
    • 不同函数的局部变量互不影响
    • 参数也是局部变量

    def add(a, b):
    result = a + b # result是局部变量
    return result

    # a, b, result 在函数外部均不存在

    局部变量的生命周期

    def counter():
    count = 0
    count += 1
    return count

    print(counter()) # 1
    print(counter()) # 1(每次调用都会重新创建count,不会累加)

    如果需要记住多次调用的状态,可以使用全局变量或闭包(后续讲解)。


    三、全局变量(Global Variable)

    在函数外部(模块顶层)定义的变量,可以被整个模块的所有函数访问(读取),但修改需要特殊声明。

    3.1 读取全局变量

    g = 100 # 全局变量

    def show():
    print(g) # 可以读取

    show() # 输出100

    3.2 修改全局变量:global关键字

    在函数内部,如果直接对全局变量赋值,Python会创建一个同名的局部变量,而不是修改全局变量。

    g = 100

    def modify_wrong():
    g = 200 # 这里创建了一个新的局部变量g,全局g不变
    print(g) # 200

    modify_wrong()
    print(g) # 100(全局变量未被修改)

    要修改全局变量,必须使用global声明。

    def modify_correct():
    global g
    g = 200 # 现在修改的是全局变量

    modify_correct()
    print(g) # 200

    3.3 何时使用全局变量

    • 常量定义:如PI = 3.14159,虽然不是严格不可变,但约定全大写表示常量。
    • 配置参数:跨多个函数共享的配置。
    • 缓存/计数器:需要在函数调用间保持状态(但更推荐使用闭包或类)。

    💡 工作应用:过度使用全局变量会导致代码难以调试和维护,因为任何函数都可能修改它。推荐尽量使用参数传递和返回值,保持函数的“纯度”。


    四、LEGB规则详解

    当你在代码中使用一个变量时,Python按照Local → Enclosing → Global → Built-in的顺序查找。

    4.1 各层级示例

    # Built-in: Python内置的函数和异常等
    print(len("hello")) # len来自built-in

    # Global: 模块级变量
    x = "global"

    def outer():
    # Enclosing: 外层函数变量
    y = "enclosing"

    def inner():
    # Local: 内层函数局部变量
    z = "local"
    print(x, y, z) # 查找x: 跳过local/enclosing未找到,找到global的x
    inner()

    outer()

    4.2 屏蔽效应

    内层作用域的变量会“屏蔽”外层同名的变量。

    x = "global"

    def func():
    x = "local" # 创建局部变量,屏蔽全局
    print(x)

    func() # local
    print(x) # global

    4.3 内置作用域示例

    # 错误示例:覆盖内置函数
    len = 10
    print(len("hello")) # TypeError: 'int' object is not callable

    # 正确:不要使用内置函数名作为变量名


    五、嵌套函数与nonlocal关键字

    函数内部可以再定义函数,称为嵌套函数。内层函数可以访问外层函数的变量(即Enclosing作用域),但是不能直接赋值修改,除非使用nonlocal。

    5.1 访问外层变量(只读)

    def outer():
    msg = "Hello"
    def inner():
    print(msg) # 可以读取外层变量
    inner()

    outer() # Hello

    5.2 修改外层变量:nonlocal

    类似于global,但nonlocal用于嵌套函数中修改外层(非全局)的变量。

    def outer():
    count = 0
    def inner():
    nonlocal count # 声明count不是局部变量,而是外层函数的变量
    count += 1
    print(count)
    return inner # 返回内部函数(闭包)

    f = outer()
    f() # 1
    f() # 2

    🔥 面试考点:“nonlocal和global的区别?”答:global用于修改全局变量;nonlocal用于修改嵌套函数中外层函数的变量(不能是全局)。

    5.3 多层嵌套

    nonlocal会向上查找最近一层的对应变量(跳过全局)。

    def outer():
    x = "outer"
    def middle():
    x = "middle" # 这一层的x
    def inner():
    nonlocal x # 这里指向middle的x,而不是outer的
    x = "inner"
    inner()
    print("middle:", x)
    middle()
    print("outer:", x)

    outer()
    # 输出:
    # middle: inner
    # outer: outer


    六、闭包(Closure)基础

    闭包是函数式编程中的一个重要概念。当一个嵌套函数引用了外层函数的变量,并且外层函数返回了这个嵌套函数时,就形成了闭包。闭包让函数可以“记住”其定义时的环境。

    6.1 闭包的形成条件

  • 必须有一个嵌套函数(内层函数)。
  • 内层函数必须引用外层函数的变量。
  • 外层函数必须返回内层函数。
  • def make_multiplier(factor):
    """返回一个函数,该函数将输入乘以factor"""
    def multiplier(x):
    return x * factor # 引用外层变量factor
    return multiplier

    # 创建闭包
    double = make_multiplier(2)
    triple = make_multiplier(3)

    print(double(5)) # 10
    print(triple(5)) # 15

    6.2 闭包的作用

    • 数据隐藏/封装:闭包中的变量不对外暴露,只能通过返回的函数访问。
    • 代替小型类:当只需要一个简单状态时,闭包比类更轻量。
    • 装饰器的基础:Python装饰器本质就是闭包。

    6.3 查看闭包中的变量

    闭包会将引用的外层变量保存在__closure__属性中。

    def outer():
    x = 10
    y = 20
    def inner():
    return x + y
    return inner

    f = outer()
    print(f.__closure__) # 显示闭包信息
    print(f.__closure__[0].cell_contents) # 10
    print(f.__closure__[1].cell_contents) # 20

    6.4 常见误区:循环中创建闭包

    # 错误的闭包:共享同一个变量
    funcs = []
    for i in range(3):
    def f():
    return i
    funcs.append(f)

    for f in funcs:
    print(f()) # 都输出2,因为i最后变成2,所有f都引用同一个i

    # 正确的做法:使用默认参数绑定当前值
    funcs = []
    for i in range(3):
    def f(i=i): # 默认参数将当前i的值绑定
    return i
    funcs.append(f)

    for f in funcs:
    print(f()) # 0 1 2


    七、作用域与变量生存周期

    • 全局变量:从模块加载到程序结束一直存在。
    • 局部变量:函数调用时创建,函数返回时销毁。
    • 闭包中的外层变量:即使外层函数已经返回,被内层函数引用的变量依然存在(通过闭包保持引用)。

    def outer():
    value = [0] # 使用列表可变对象,可以在内层函数中修改
    def inner():
    value[0] += 1
    return value[0]
    return inner

    counter = outer()
    print(counter()) # 1
    print(counter()) # 2
    # value这个列表仍然存在,被闭包引用,不会被销毁


    💻 代码案例实操

    案例1:局部变量与全局变量基础演示

    """
    scope_basic.py
    演示局部和全局变量的基本行为
    """

    # 全局变量
    global_var = 100

    def func1():
    # 局部变量,与全局同名但不影响
    global_var = 200
    print("func1内部:", global_var)

    def func2():
    # 读取全局变量(没有局部同名变量)
    print("func2内部:", global_var)

    def func3():
    # 声明要修改全局变量
    global global_var
    global_var = 300
    print("func3内部修改:", global_var)

    print("初始全局:", global_var) # 100
    func1() # 200
    print("调用func1后全局:", global_var) # 100(未变)
    func2() # 100
    func3() # 300
    print("调用func3后全局:", global_var) # 300

    案例2:LEGB规则完整演示

    """
    legb_demo.py
    演示Local, Enclosing, Global, Built-in的查找顺序
    """

    # 全局变量
    x = "global x"

    def outer():
    # Enclosing变量
    x = "enclosing x"

    def inner():
    # Local变量
    x = "local x"
    print("inner内:", x) # 查找: Local找到
    inner()

    def inner2():
    # 没有局部x,查找Enclosing
    print("inner2内:", x) # enclosing x
    inner2()

    def inner3():
    # 使用global关键字强制从全局找
    global x
    print("inner3内(global):", x) # global x
    inner3()

    outer()
    print("全局:", x) # global x

    # 内置作用域示例
    import builtins
    print(dir(builtins)) # 查看所有内置函数/变量

    # 屏蔽内置变量
    len = 10
    print(len) # 10
    # print(len("hi")) # 报错,因为len现在是整数
    del len # 删除局部len
    print(len("hi")) # 2,恢复内置

    案例3:nonlocal深入理解

    """
    nonlocal_demo.py
    演示nonlocal关键字的使用和多层嵌套
    """

    def outer():
    count = 0
    def increment():
    nonlocal count # 声明count来自外层(outer)
    count += 1
    return count
    return increment

    counter = outer()
    print(counter()) # 1
    print(counter()) # 2

    def multiple_layers():
    a = 10
    def middle():
    b = 20
    def inner():
    nonlocal a # 引用middle? 不,nonlocal会跳过局部,找最近的非全局作用域,这里是outer的a
    nonlocal b # 引用middle的b
    a += 1
    b += 1
    inner()
    print("middle b:", b)
    middle()
    print("outer a:", a)

    multiple_layers()
    # 输出:
    # middle b: 21
    # outer a: 11

    案例4:闭包实现计数器

    """
    closure_counter.py
    使用闭包实现多种计数器
    """

    def make_counter(initial=0):
    """返回一个计数器闭包,可以增加、减少、重置"""
    count = initial

    def increment():
    nonlocal count
    count += 1
    return count

    def decrement():
    nonlocal count
    count -= 1
    return count

    def reset():
    nonlocal count
    count = initial
    return count

    def get():
    return count

    # 返回包含多个函数的字典或对象
    return {"inc": increment, "dec": decrement, "reset": reset, "get": get}

    # 创建计数器
    c1 = make_counter(10)
    print(c1["inc"]()) # 11
    print(c1["inc"]()) # 12
    print(c1["dec"]()) # 11
    print(c1["get"]()) # 11
    c1["reset"]()
    print(c1["get"]()) # 10

    # 创建另一个独立计数器
    c2 = make_counter(100)
    print(c2["inc"]()) # 101
    print(c2["get"]()) # 101

    案例5:闭包实现简单的缓存(记忆化)

    """
    memoization_closure.py
    使用闭包实现函数结果缓存(面试常考)
    """

    def memoize(func):
    """装饰器风格的闭包,但这里演示手动闭包"""
    cache = {}

    def wrapper(*args):
    if args not in cache:
    print(f"计算 {args} 的结果…")
    cache[args] = func(*args)
    else:
    print(f"从缓存获取 {args} 的结果")
    return cache[args]

    return wrapper

    # 一个耗时的计算函数
    def slow_fibonacci(n):
    if n < 2:
    return n
    return slow_fibonacci(n1) + slow_fibonacci(n2)

    # 使用闭包包装
    fib_with_cache = memoize(slow_fibonacci)

    print(fib_with_cache(35)) # 第一次,计算较慢
    print(fib_with_cache(35)) # 第二次,从缓存快速返回

    # 工厂函数:生成带缓存的任意函数
    def make_cached(func):
    cache = {}
    def cached_func(*args):
    if args in cache:
    return cache[args]
    result = func(*args)
    cache[args] = result
    return result
    return cached_func

    # 应用于阶乘
    def factorial(n):
    if n <= 1:
    return 1
    return n * factorial(n1)

    fact_cached = make_cached(factorial)
    print(fact_cached(10)) # 计算
    print(fact_cached(10)) # 缓存

    案例6:循环闭包陷阱及解决

    """
    loop_closure_trap.py
    演示循环中创建闭包的经典问题及解决方案
    """

    print("=== 错误示例 ===")
    funcs = []
    for i in range(3):
    def f():
    return i # 引用循环变量i
    funcs.append(f)

    for f in funcs:
    print(f()) # 都输出2,因为所有f共享同一个i,循环结束后i=2

    print("\\n=== 解决方案1:默认参数绑定当前值 ===")
    funcs2 = []
    for i in range(3):
    def f(i=i): # 默认参数在定义时绑定当前i的值
    return i
    funcs2.append(f)

    for f in funcs2:
    print(f()) # 0 1 2

    print("\\n=== 解决方案2:使用外层函数创建闭包(工厂函数) ===")
    def create_func(x):
    def f():
    return x
    return f

    funcs3 = [create_func(i) for i in range(3)]
    for f in funcs3:
    print(f()) # 0 1 2

    print("\\n=== 解决方案3:使用functools.partial ===")
    from functools import partial
    funcs4 = [partial(lambda x: x, i) for i in range(3)]
    for f in funcs4:
    print(f()) # 0 1 2

    案例7:实际工作场景——配置管理

    """
    config_closure.py
    使用闭包管理配置信息
    """

    def make_config(initial_config=None):
    """返回一个配置管理闭包,可以获取、设置、更新配置"""
    config = initial_config.copy() if initial_config else {}

    def get(key=None):
    if key is None:
    return config.copy() # 返回副本避免外部修改
    return config.get(key)

    def set(key, value):
    config[key] = value

    def update(new_config):
    config.update(new_config)

    return {"get": get, "set": set, "update": update}

    # 创建配置实例
    app_config = make_config({"debug": False, "host": "localhost"})
    print(app_config["get"]()) # {'debug': False, 'host': 'localhost'}
    app_config["set"]("debug", True)
    print(app_config["get"]("debug")) # True
    app_config["update"]({"port": 8080})
    print(app_config["get"]()) # {'debug': True, 'host': 'localhost', 'port': 8080}

    # 另一个独立的配置
    db_config = make_config({"user": "admin", "password": "123"})
    print(db_config["get"]("user")) # admin
    # app_config不受影响
    print(app_config["get"]("user")) # None


    ⚠️ 易错点避坑总结

    序号坑点描述后果解决方案
    1 函数内直接给全局变量赋值,以为会修改全局变量 创建了局部变量,全局未变 使用global声明
    2 在嵌套函数内修改外层变量时忘记nonlocal 创建了新的局部变量 使用nonlocal声明
    3 循环中创建闭包引用循环变量 所有闭包共享同一个变量,结果不符合预期 用默认参数绑定当前值,或使用工厂函数
    4 混淆global和nonlocal 语法错误或逻辑错误 记住:全局用global,嵌套用nonlocal
    5 在函数内部使用与内置函数同名的变量 覆盖内置函数,导致后续调用失败 避免使用len、list等作为变量名
    6 尝试在函数内部修改全局的可变对象(如列表)时,以为需要global 实际上修改列表内容不需要global 区分“重新赋值”和“修改对象内容”
    7 闭包中引用的变量是不可变类型,却直接赋值 创建了新的局部变量,未修改外层 使用nonlocal,或使用可变容器(列表)
    8 过度使用全局变量 代码耦合高,难以调试 尽量使用参数传递和返回值
    9 不理解LEGB,在嵌套函数中误用了外层变量 变量查找错误 记住查找顺序,必要时使用print(locals())调试
    10 闭包返回后,以为外层变量会被销毁 实际上闭包保留了引用,变量仍然存在 理解闭包的内存机制

    📝 课后实战练习题

    第1题:全局与局部变量分析

    阅读以下代码,写出输出结果,并解释原因。

    a = 10
    def func():
    print(a)
    a = 20
    print(a)
    func()
    print(a)

    (提示:这会产生UnboundLocalError,解释为什么)

    第2题:正确使用global

    修改上面的代码,使其能正确输出:10(第一次打印全局)、20(局部修改)、20(全局修改)。使用global关键字。

    第3题:嵌套函数与nonlocal

    编写一个函数outer(),内部定义count = 0,再定义一个inner()函数,调用inner()可以使count增加1并打印。要求inner作为返回值,并在外部调用两次,观察输出。

    第4题:闭包实现简单的平均值计算器

    创建一个闭包make_averager(),它返回一个函数,该函数接收一个数值,并返回到目前为止所有传入数值的平均值。例如:

    avg = make_averager()
    print(avg(10)) # 10.0
    print(avg(20)) # 15.0
    print(avg(30)) # 20.0

    提示:使用列表或nonlocal保存历史数据。

    第5题:循环闭包陷阱修复

    给定以下代码,预期输出0, 1, 2, 3, 4,但实际输出4,4,4,4,4。请用三种方法修复它。

    functions = []
    for i in range(5):
    def f():
    return i
    functions.append(f)

    for f in functions:
    print(f())

    第6题:LEGB查找顺序验证

    在不运行代码的情况下,写出以下程序的输出,并说明每一步的查找过程。

    x = "global"
    def outer():
    x = "outer"
    def inner():
    x = "inner"
    print(x)
    inner()
    outer()

    再修改:删除inner内的x = "inner",输出是什么?再删除outer内的x = "outer",输出是什么?

    第7题:综合应用——带重置功能的计数器

    编写一个闭包函数create_counter(start=0, step=1),返回三个函数:next()返回下一个值,reset()重置到起始值,set_step(new_step)修改步长。要求多个计数器独立。示例:

    c = create_counter(10, 2)
    print(c["next"]()) # 10
    print(c["next"]()) # 12
    c["set_step"](3)
    print(c["next"]()) # 15
    c["reset"]()
    print(c["next"]()) # 10


    🧠 知识点思维导图总结

    #mermaid-svg-Nti4jnnMOkA15CqX{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Nti4jnnMOkA15CqX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Nti4jnnMOkA15CqX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Nti4jnnMOkA15CqX .error-icon{fill:#552222;}#mermaid-svg-Nti4jnnMOkA15CqX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Nti4jnnMOkA15CqX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Nti4jnnMOkA15CqX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Nti4jnnMOkA15CqX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Nti4jnnMOkA15CqX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Nti4jnnMOkA15CqX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Nti4jnnMOkA15CqX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Nti4jnnMOkA15CqX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Nti4jnnMOkA15CqX .marker.cross{stroke:#333333;}#mermaid-svg-Nti4jnnMOkA15CqX svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Nti4jnnMOkA15CqX p{margin:0;}#mermaid-svg-Nti4jnnMOkA15CqX .edge{stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .section–1 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section–1 path,#mermaid-svg-Nti4jnnMOkA15CqX .section–1 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section–1 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section–1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section–1 text{fill:#ffffff;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon–1{font-size:40px;color:#ffffff;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge–1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth–1{stroke-width:17;}#mermaid-svg-Nti4jnnMOkA15CqX .section–1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-0 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-0 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-0 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-0 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-0 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-0{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-0{stroke-width:14;}#mermaid-svg-Nti4jnnMOkA15CqX .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-1 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-1 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-1 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-1 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-1 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-1{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-1{stroke-width:11;}#mermaid-svg-Nti4jnnMOkA15CqX .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-2 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-2 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-2 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-2 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-2 text{fill:#ffffff;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-2{stroke-width:8;}#mermaid-svg-Nti4jnnMOkA15CqX .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-3 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-3 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-3 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-3 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-3 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-3{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-3{stroke-width:5;}#mermaid-svg-Nti4jnnMOkA15CqX .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-4 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-4 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-4 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-4 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-4 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-4{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-4{stroke-width:2;}#mermaid-svg-Nti4jnnMOkA15CqX .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-5 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-5 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-5 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-5 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-5 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-5{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-5{stroke-width:-1;}#mermaid-svg-Nti4jnnMOkA15CqX .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-6 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-6 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-6 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-6 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-6 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-6{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-6{stroke-width:-4;}#mermaid-svg-Nti4jnnMOkA15CqX .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-7 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-7 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-7 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-7 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-7 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-7{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-7{stroke-width:-7;}#mermaid-svg-Nti4jnnMOkA15CqX .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-8 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-8 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-8 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-8 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-8 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-8{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-8{stroke-width:-10;}#mermaid-svg-Nti4jnnMOkA15CqX .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-9 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-9 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-9 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-9 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-9 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-9{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-9{stroke-width:-13;}#mermaid-svg-Nti4jnnMOkA15CqX .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-10 rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-10 path,#mermaid-svg-Nti4jnnMOkA15CqX .section-10 circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-10 polygon,#mermaid-svg-Nti4jnnMOkA15CqX .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-10 text{fill:black;}#mermaid-svg-Nti4jnnMOkA15CqX .node-icon-10{font-size:40px;color:black;}#mermaid-svg-Nti4jnnMOkA15CqX .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .edge-depth-10{stroke-width:-16;}#mermaid-svg-Nti4jnnMOkA15CqX .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled,#mermaid-svg-Nti4jnnMOkA15CqX .disabled circle,#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:lightgray;}#mermaid-svg-Nti4jnnMOkA15CqX .disabled text{fill:#efefef;}#mermaid-svg-Nti4jnnMOkA15CqX .section-root rect,#mermaid-svg-Nti4jnnMOkA15CqX .section-root path,#mermaid-svg-Nti4jnnMOkA15CqX .section-root circle,#mermaid-svg-Nti4jnnMOkA15CqX .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-Nti4jnnMOkA15CqX .section-root text{fill:#ffffff;}#mermaid-svg-Nti4jnnMOkA15CqX .section-root span{color:#ffffff;}#mermaid-svg-Nti4jnnMOkA15CqX .section-2 span{color:#ffffff;}#mermaid-svg-Nti4jnnMOkA15CqX .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-Nti4jnnMOkA15CqX .edge{fill:none;}#mermaid-svg-Nti4jnnMOkA15CqX .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-Nti4jnnMOkA15CqX :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    第13课:作用域与闭包

    作用域分类

    局部作用域 Local

    嵌套作用域 Enclosing

    全局作用域 Global

    内置作用域 Built-in

    LEGB规则

    查找顺序

    屏蔽效应

    global关键字

    修改全局变量

    常量定义

    nonlocal关键字

    修改外层嵌套变量

    与global的区别

    闭包Closure

    形成条件

    嵌套函数

    引用外层变量

    返回内层函数

    作用

    数据隐藏

    代替小类

    装饰器基础

    常见陷阱

    循环中创建闭包

    可变对象vs不可变

    面试考点

    LEGB顺序

    global vs nonlocal

    闭包定义与用途

    循环闭包解决方案


    🔜 下节课预告

    闭包是一个函数“记住”了外层变量的值。如果我们将函数作为参数传递或作为返回值,就引出了高阶函数的概念。下一节课我们将学习Python中的高阶函数、lambda表达式以及内置的高阶函数map、filter、sorted。

    第14课:高阶函数、lambda匿名函数、map/filter/sorted内置高阶函数实战

    内容包括:

    • Lambda匿名函数的语法与使用场景
    • 高阶函数的概念
    • map:对可迭代对象每个元素应用函数
    • filter:过滤可迭代对象元素
    • sorted:灵活排序(key参数)
    • 结合lambda实现简洁的数据处理
    • 实战:数据清洗、排序、转换

    高阶函数是函数式编程的基石,掌握它能让你的代码更简洁、更Pythonic。

    🌟 学习鼓励:作用域和闭包是Python进阶的第一个门槛。你可能需要多花一些时间理解nonlocal和闭包的内存行为。请务必亲手调试文中的案例,观察变量的id或__closure__属性,你一定会有豁然开朗的感觉。坚持就是胜利!


    🔗《50节课 Python 从入门到精通》系列课程导航

    去订阅

    🌟 感谢您耐心阅读到这里! 💡 如果本文对您有所启发欢迎: 👍 点赞📌 收藏 📤 分享给更多需要的伙伴。 🗣️ 期待在评论区看到您的想法, 共同进步。 🔔 关注我,持续获取更多干货内容~ 🤗 我们下篇文章见~

    赞(0)
    未经允许不得转载:171主机测评 » 第13课:Python|局部变量|全局变量|函数作用域与闭包基础精讲
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址