====== 第十二章:函数高级特性 ====== ===== 本章目标 ===== 完成本章学习后,你将能够: * 理解闭包和装饰器 * 掌握函数柯里化和偏函数 * 使用 functools 模块的工具 * 理解生成器函数 * 掌握上下文管理器 ===== 闭包(Closure) ===== ==== 什么是闭包 ==== 闭包是**引用了外部变量**的函数,即使外部函数已经执行完毕,闭包仍然可以访问这些变量。 def outer_function(x): def inner_function(y): return x + y # inner引用了外部变量x return inner_function # 创建闭包 add_10 = outer_function(10) add_20 = outer_function(20) print(add_10(5)) # 15 print(add_20(5)) # 25 # add_10和add_20各自保存了不同的x值 ==== 闭包的应用 ==== # 计数器 def make_counter(): count = 0 def counter(): nonlocal count count += 1 return count return counter c1 = make_counter() c2 = make_counter() print(c1()) # 1 print(c1()) # 2 print(c2()) # 1(独立的计数器) # 函数记忆化(简单版) def memoize(func): cache = {} def wrapper(*args): if args not in cache: cache[args] = func(*args) return cache[args] return wrapper ===== 装饰器(Decorator) ===== ==== 基础装饰器 ==== def my_decorator(func): def wrapper(*args, **kwargs): print("函数执行前") result = func(*args, **kwargs) print("函数执行后") return result return wrapper @my_decorator def say_hello(): print("Hello!") say_hello() # 输出: # 函数执行前 # Hello! # 函数执行后 ==== 带参数的装饰器 ==== def repeat(times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(times): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(times=3) def greet(name): print(f"Hello, {name}!") greet("Alice") # 输出3次 Hello, Alice! ==== 实用装饰器示例 ==== import time from functools import wraps # 计时装饰器 def timer(func): @wraps(func) # 保留原函数元数据 def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) elapsed = time.time() - start print(f"{func.__name__} 耗时: {elapsed:.4f}秒") return result return wrapper # 调试装饰器 def debug(func): @wraps(func) def wrapper(*args, **kwargs): args_repr = [repr(a) for a in args] kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()] signature = ", ".join(args_repr + kwargs_repr) print(f"调用 {func.__name__}({signature})") result = func(*args, **kwargs) print(f"{func.__name__} 返回 {result!r}") return result return wrapper # 重试装饰器 def retry(max_attempts=3, delay=1): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): attempts = 0 while attempts < max_attempts: try: return func(*args, **kwargs) except Exception as e: attempts += 1 if attempts == max_attempts: raise print(f"尝试 {attempts} 失败: {e},{delay}秒后重试...") time.sleep(delay) return None return wrapper return decorator ===== functools 模块 ===== ==== partial - 偏函数 ==== from functools import partial # 固定某些参数 basetwo = partial(int, base=2) print(basetwo('10010')) # 18 # 实际应用 import json print_json = partial(json.dumps, indent=2, ensure_ascii=False) data = {"name": "中文", "age": 25} print(print_json(data)) ==== reduce ==== from functools import reduce # 累积计算 nums = [1, 2, 3, 4, 5] product = reduce(lambda x, y: x * y, nums) # 120 # 带初始值 sum_with_initial = reduce(lambda x, y: x + y, nums, 10) # 25 # 找最大值 maximum = reduce(lambda x, y: x if x > y else y, nums) ==== lru_cache ==== from functools import lru_cache @lru_cache(maxsize=128) def fibonacci(n): if n < 2: return n return fibonacci(n - 1) + fibonacci(n - 2) print(fibonacci(100)) # 瞬间完成 # 查看缓存信息 print(fibonacci.cache_info()) # CacheInfo(hits=98, misses=101, maxsize=128, currsize=101) ===== 生成器函数 ===== # 生成器函数使用yield代替return def countdown(n): while n > 0: yield n n -= 1 # 使用 for num in countdown(5): print(num) # 5, 4, 3, 2, 1 # 生成器表达式 gen = (x ** 2 for x in range(10)) print(sum(gen)) # 285 # yield from:委托给子生成器 def flatten(nested): for item in nested: if isinstance(item, list): yield from flatten(item) else: yield item print(list(flatten([1, [2, [3, 4]], 5]))) # [1, 2, 3, 4, 5] ===== 上下文管理器 ===== # 使用with语句 with open("file.txt") as f: content = f.read() # 自定义上下文管理器 class ManagedResource: def __enter__(self): print("资源获取") return self def __exit__(self, exc_type, exc_val, exc_tb): print("资源释放") return False # 不抑制异常 with ManagedResource() as resource: print("使用资源") # 使用contextmanager装饰器 from contextlib import contextmanager @contextmanager def managed_file(filename): print(f"打开文件: {filename}") f = open(filename, 'w') try: yield f finally: f.close() print(f"关闭文件: {filename}") with managed_file("test.txt") as f: f.write("Hello") ===== 本章小结 ===== 本章我们学习了: * 闭包的概念和应用 * 装饰器的编写和使用 * functools模块的工具 * 生成器函数的高级用法 * 上下文管理器 下一章:[[python_course:chapter13|第十三章:面向对象编程基础]]