Skip to content

第二章|函数、作用域与闭包 ​

本章目标 ​

深入理解 Python 函数机制:如何定义和调用函数、作用域规则、闭包的工作原理、灵活的参数模型。

从基本的函数定义开始,理解 LEGB 作用域规则,掌握闭包的状态封装能力,最后学习 Python 强大而灵活的参数系统。

学习路径 ​

按顺序阅读以下文章,每篇包含讲解、示例和练习:

  1. 函数:定义、参数、返回值与调用
    学习函数定义、参数传递、返回值、默认参数值、文档字符串、lambda 表达式。

  2. 作用域与 LEGB:函数如何找到名字
    理解 LEGB 作用域规则、全局与本地变量、global 和 nonlocal 关键字。

  3. 闭包:捕获外层变量与生命周期
    掌握闭包概念、变量捕获机制、闭包应用场景、闭包 vs 类的选择。

  4. 参数模型:位置、关键字、解包与默认值陷阱
    学习 *args、**kwargs、参数解包、仅限位置/关键字参数、避免默认参数陷阱。

关键概念 ​

函数是一等对象 ​

Python 中函数是一等对象,可以赋值给变量、作为参数传递、从函数返回。这是函数式编程和装饰器的基础。

python
def square(x):
    return x * x

f = square  # 函数赋值
print(f(5))  # 25

def apply(func, value):
    return func(value)  # 函数作为参数

print(apply(square, 3))  # 9

LEGB 规则 ​

Python 按 Local → Enclosing → Global → Built-in 顺序查找名字。理解这个规则是掌握作用域的关键。

闭包 ​

闭包是捕获了外层作用域变量的函数。即使外层函数返回,闭包仍可访问被捕获的变量。闭包用于状态封装、工厂函数、回调等场景。

python
def make_counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment

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

灵活的参数系统 ​

Python 的参数系统支持:

  • 位置参数和关键字参数
  • *args 收集任意位置参数
  • **kwargs 收集任意关键字参数
  • / 标记仅限位置参数(Python 3.8+)
  • * 标记仅限关键字参数

这使得 Python 函数极其灵活,但也需要理解默认参数的陷阱。

前置知识 ​

  • 第一章:值、绑定与控制流
  • 理解对象与名字绑定
  • 掌握基本控制流

后续章节 ​

完成本章后,继续学习:

练习答案 ​

本章所有练习的答案和详细解释:第二章练习答案

深入阅读 ​

为什么函数是一等对象很重要? ​

函数作为对象使得高阶函数、装饰器、回调等模式成为可能。这是 Python 函数式编程能力的基础,也让代码更灵活、可复用。

何时用闭包,何时用类? ​

闭包适合:

  • 简单的状态封装(1-2 个变量)
  • 工厂函数
  • 回调函数

类适合:

  • 复杂的状态和行为
  • 多个相关方法
  • 需要继承或多态

默认参数陷阱的根本原因 ​

默认参数在函数定义时求值一次,而非每次调用时。可变对象(列表、字典)作为默认值时,所有调用共享同一对象。使用 None 作为哨兵值,在函数体内创建新对象。

global vs nonlocal ​

  • global:声明使用模块级全局变量
  • nonlocal:声明使用最近的外层函数变量(不包括全局)

两者都用于在嵌套作用域中修改外层变量。只读取不需要声明。

返回Python 学习路线 · 开始第一节

用心记录每一步成长