在编写复杂或高度可扩展的程序时,我们经常需要用到回调函数 、闭包。这两个概念在函数式编程、事件驱动编程、框架设计、中间件等领域非常重要
1. 回调函数 (Callback Function)
1.1 什么是回调函数?
回调函数 是一个作为参数传递给其他函数的函数,该函数会在某个条件满足时(例如事件触发、异步操作完成、数据处理结束等)被"回调"执行。回调将控制权转交给用户定义的逻辑,使得高层代码可以调用底层代码注册的函数,从而实现"依赖倒置"(程序在运行时决定具体行为)。
1.2 在 Python 中的应用场景
-
异步 I/O 或网络请求完成后通知主线程。
-
sort()或sorted()中的key参数。 -
GUI 编程中的按钮点击事件。
-
数据处理管线中的自定义处理步骤。
python
import time
from typing import Callable, Any
# 一个模拟异步处理的任务
def long_running_task(callback: Callable[[Any], None]) -> None:
"""模拟耗时操作,完成后调用回调函数"""
print("任务开始...")
time.sleep(2) # 模拟耗时
result = 42 # 假设计算结果
print("任务完成,准备调用回调")
callback(result) # 执行回调
def handle_result(data: Any) -> None:
"""用户自定义的回调函数"""
print(f"回调处理结果: {data * 2}")
# 使用
long_running_task(handle_result)
输出:
任务开始...
任务完成,准备调用回调
回调处理结果: 84
1.4 同步回调 vs 异步回调
-
同步回调:回调函数在调用者返回之前立即执行(如上例)。
-
异步回调:回调函数延迟执行,可能由事件循环、线程池等触发。
python
import threading
def async_task(callback):
def run():
print("异步线程工作...")
time.sleep(1)
callback("异步结果")
threading.Thread(target=run).start()
def my_callback(msg):
print(f"收到回调: {msg}")
async_task(my_callback)
print("主线程继续执行...")
注意 :Python 中的全局解释器锁(GIL)不影响回调的概念,但在高并发场景下建议使用 asyncio 或 concurrent.futures
2. 闭包 (Closure)
2.1 什么是闭包?
闭包 是一个函数,它"记住"了它被定义时所处的环境(即外部函数的局部变量),即使外部函数已经执行完毕,闭包仍然可以访问那些变量。闭包是 Python 中实现装饰器、工厂函数、延迟求值等技术的基础。
2.2 形成闭包的条件
-
存在嵌套函数(内部函数)。
-
内部函数引用了外部函数的局部变量。
-
外部函数将该内部函数作为返回值返回。
python
def make_multiplier(factor: int):
"""外部函数,返回一个闭包"""
def multiplier(x: int):
return x * factor
return multiplier
# 创建两个不同的闭包实例
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
# 检查闭包保存的变量
print(double.__closure__[0].cell_contents) # 2
2.4 闭包的实际用途
-
数据隐藏(类似轻量级的私有变量)。
-
创建带有"记忆"的函数。
-
替代某些简单的类(当只需要一个行为对象时)。
python
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
c1 = counter()
c2 = counter()
print(c1()) # 1
print(c1()) # 2
print(c2()) # 1 (独立的状态)
2.5 闭包与 lambda 表达式
Lambda 函数也可以形成闭包,但受限于单表达式语法。
python
def add_n(n):
return lambda x: x + n
add_five = add_n(5)
print(add_five(10)) # 15
闭包可以生成回调函数:
python
def make_callback_with_state(state):
def callback(data):
print(f"当前状态: {state}, 处理数据: {data}")
return callback
callback_func = make_callback_with_state("ready")
# 以后把这个 callback_func 注册给某个事件处理系统
总结
-
回调函数是实现"你完成时叫我"的标准化手段,是异步编程和事件循环的核心。
-
闭包是 Python 中函数式编程的重要构件,它可以"捕获"外部变量,实现状态保持。