2025-10-22
python
00

目录

Python 闭包 (Closure)
1. 闭包的基本概念
基本特征:
2. 基本闭包示例
3. 闭包的经典应用
计数器
幂函数生成器
4. 闭包的实际应用场景
配置函数
缓存装饰器
5. 闭包与状态保持
银行账户模拟
6. 闭包在装饰器中的应用
7. 闭包的高级用法
函数工厂
配置化的验证器
8. 闭包与 lambda 结合
9. 闭包的注意事项
变量捕获问题
内存泄漏风险
10. 实际项目中的应用
配置管理器
总结
闭包的优点:
适用场景:
注意事项:

Python 闭包 (Closure)

1. 闭包的基本概念

闭包是指一个函数能够记住并访问其词法作用域中的变量,即使该函数在其作用域之外执行。

基本特征:

  • 嵌套函数
  • 内部函数引用外部函数的变量
  • 外部函数返回内部函数

2. 基本闭包示例

python
def outer_function(msg): # 外部函数的变量 message = msg def inner_function(): # 内部函数引用外部函数的变量 print(message) # 返回内部函数(不执行) return inner_function # 使用闭包 hello_func = outer_function("Hello") world_func = outer_function("World") hello_func() # 输出: Hello world_func() # 输出: World

3. 闭包的经典应用

计数器

python
def counter(): count = 0 def increment(): nonlocal count # 声明使用外部变量 count += 1 return count return increment # 创建两个独立的计数器 counter1 = counter() counter2 = counter() print(counter1()) # 1 print(counter1()) # 2 print(counter1()) # 3 print(counter2()) # 1 - 独立的计数器 print(counter2()) # 2

幂函数生成器

python
def power_factory(exponent): def power(base): return base ** exponent return power # 创建不同的幂函数 square = power_factory(2) cube = power_factory(3) sqrt = power_factory(0.5) print(square(5)) # 25 (5^2) print(cube(3)) # 27 (3^3) print(sqrt(16)) # 4.0 (16^0.5)

4. 闭包的实际应用场景

配置函数

python
def make_greeting(greeting_word): def greet(name): return f"{greeting_word}, {name}!" return greet # 创建不同的问候函数 say_hello = make_greeting("Hello") say_hi = make_greeting("Hi") say_hola = make_greeting("Hola") print(say_hello("Alice")) # Hello, Alice! print(say_hi("Bob")) # Hi, Bob! print(say_hola("Charlie")) # Hola, Charlie!

缓存装饰器

python
def cache_decorator(func): cache = {} def wrapper(*args): if args in cache: print(f"从缓存中获取结果: {args}") return cache[args] print(f"计算新结果: {args}") result = func(*args) cache[args] = result return result return wrapper # 使用缓存装饰器 @cache_decorator def expensive_calculation(x, y): return x * y + x ** 2 + y ** 2 # 测试 print(expensive_calculation(2, 3)) # 计算新结果 print(expensive_calculation(2, 3)) # 从缓存中获取结果 print(expensive_calculation(4, 5)) # 计算新结果 print(expensive_calculation(4, 5)) # 从缓存中获取结果

5. 闭包与状态保持

银行账户模拟

python
def create_account(initial_balance=0): balance = initial_balance def deposit(amount): nonlocal balance balance += amount return f"存款 {amount}, 当前余额: {balance}" def withdraw(amount): nonlocal balance if amount <= balance: balance -= amount return f"取款 {amount}, 当前余额: {balance}" else: return f"余额不足! 当前余额: {balance}" def get_balance(): return f"当前余额: {balance}" # 返回多个内部函数 return { 'deposit': deposit, 'withdraw': withdraw, 'get_balance': get_balance } # 创建账户 account1 = create_account(1000) account2 = create_account(500) print(account1['deposit'](200)) # 存款 200, 当前余额: 1200 print(account1['withdraw'](300)) # 取款 300, 当前余额: 900 print(account1['get_balance']()) # 当前余额: 900 print(account2['get_balance']()) # 当前余额: 500

6. 闭包在装饰器中的应用

python
# 计时装饰器 import time def timer_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"函数 {func.__name__} 执行时间: {end_time - start_time:.4f}秒") return result return wrapper # 重试装饰器 def retry_decorator(max_retries=3, delay=1): def decorator(func): def wrapper(*args, **kwargs): for attempt in range(max_retries): try: return func(*args, **kwargs) except Exception as e: print(f"尝试 {attempt + 1} 失败: {e}") if attempt < max_retries - 1: time.sleep(delay) raise Exception(f"函数 {func.__name__}{max_retries} 次尝试后仍然失败") return wrapper return decorator # 使用装饰器 @timer_decorator @retry_decorator(max_retries=2, delay=0.5) def risky_operation(x, y): # 模拟可能失败的操作 if x + y < 10: raise ValueError("和太小了!") return x * y # 测试 try: result = risky_operation(5, 6) print(f"结果: {result}") except Exception as e: print(f"错误: {e}")

7. 闭包的高级用法

函数工厂

python
def math_operation_factory(operation): if operation == "add": def add(a, b): return a + b return add elif operation == "multiply": def multiply(a, b): return a * b return multiply elif operation == "power": def power(a, b): return a ** b return power # 创建不同的数学操作函数 adder = math_operation_factory("add") multiplier = math_operation_factory("multiply") power_func = math_operation_factory("power") print(adder(5, 3)) # 8 print(multiplier(5, 3)) # 15 print(power_func(2, 3)) # 8

配置化的验证器

python
def create_validator(min_value=None, max_value=None, data_type=None): def validator(value): errors = [] if data_type and not isinstance(value, data_type): errors.append(f"值必须是 {data_type} 类型") if min_value is not None and value < min_value: errors.append(f"值不能小于 {min_value}") if max_value is not None and value > max_value: errors.append(f"值不能大于 {max_value}") return len(errors) == 0, errors return validator # 创建不同的验证器 age_validator = create_validator(min_value=0, max_value=150, data_type=int) score_validator = create_validator(min_value=0, max_value=100, data_type=(int, float)) name_validator = create_validator(data_type=str) # 测试验证器 print(age_validator(25)) # (True, []) print(age_validator(-5)) # (False, ['值不能小于 0']) print(score_validator(85.5)) # (True, []) print(name_validator("Alice")) # (True, [])

8. 闭包与 lambda 结合

python
def multiplier_factory(n): return lambda x: x * n # 创建不同的乘数函数 double = multiplier_factory(2) triple = multiplier_factory(3) times_ten = multiplier_factory(10) print(double(5)) # 10 print(triple(5)) # 15 print(times_ten(5)) # 50

9. 闭包的注意事项

变量捕获问题

python
def create_functions(): functions = [] for i in range(3): def func(): return i functions.append(func) return functions # 问题:所有函数都返回相同的值 funcs = create_functions() for f in funcs: print(f()) # 全部输出 2,不是预期的 0, 1, 2 # 解决方案:使用默认参数 def create_functions_fixed(): functions = [] for i in range(3): def func(x=i): # 使用默认参数捕获当前值 return x functions.append(func) return functions funcs_fixed = create_functions_fixed() for f in funcs_fixed: print(f()) # 正确输出 0, 1, 2

内存泄漏风险

python
def outer(): large_data = [i for i in range(1000000)] # 大量数据 def inner(): return len(large_data) return inner # 即使只使用inner函数,large_data也会一直存在于内存中 closure_func = outer() print(closure_func()) # 当不再需要时,显式删除引用 del closure_func

10. 实际项目中的应用

配置管理器

python
def create_config_manager(default_config): config = default_config.copy() def set_config(key, value): nonlocal config config[key] = value return f"设置 {key} = {value}" def get_config(key=None): if key is None: return config.copy() return config.get(key) def reset_config(): nonlocal config config = default_config.copy() return "配置已重置" return { 'set': set_config, 'get': get_config, 'reset': reset_config } # 使用配置管理器 default_settings = {'theme': 'light', 'language': 'zh', 'notifications': True} config_manager = create_config_manager(default_settings) print(config_manager['set']('theme', 'dark')) print(config_manager['get']('theme')) # dark print(config_manager['get']()) # 所有配置 print(config_manager['reset']()) print(config_manager['get']('theme')) # light (恢复默认)

总结

闭包的优点:

  1. 数据封装:可以创建私有变量
  2. 状态保持:函数可以记住之前的状态
  3. 代码复用:可以创建相似的函数
  4. 灵活性:可以动态生成函数

适用场景:

  • 装饰器
  • 回调函数
  • 函数工厂
  • 配置管理
  • 状态机

注意事项:

  • 注意变量捕获时机
  • 避免意外的内存泄漏
  • 合理使用 nonlocal 关键字

闭包是Python函数式编程的重要特性,合理使用可以让代码更加简洁和强大。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:李佳玮

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!