
九块路线总览见《Python 到 FastAPI 九层进阶》。第七块暴露了调度、取消与资源释放等重复控制逻辑。Python 的高级机制可以把这些模式封装起来,但前提是使用者仍能看清执行时机与状态边界。
老李接手过一段“聪明代码”:三层装饰器悄悄重试、缓存并吞掉异常,调用处只有一行,却没人能解释一次调用实际执行几遍。抽象减少重复,也必须保留可观察性。
这一块的验收标准是:能用协议封装惰性遍历、横切逻辑和资源生命周期,并判断何时简单函数比元编程更合适
这一块按“迭代器—生成器—装饰器—上下文—描述符—工具组合”推进。每种技巧都先说明执行时机,再说明不该使用的边界。
官方概念
iter() 获取迭代器,next() 请求下一个值;耗尽时抛出 StopIteration。可迭代对象可创建新迭代器,迭代器通常返回自身并保存当前进度。
类比记忆
像书架与书签:书架可生成多个独立书签,书签只记录一次阅读进度,翻到末页便报告结束。
class Countdown:
def __init__(self, start: int) -> None:
self.current = start
def __iter__(self):
return self
def __next__(self) -> int:
if self.current == 0:
raise StopIteration
value = self.current
self.current -= 1
return value
print(list(Countdown(3)))
运行输出:
[3, 2, 1]
使用边界
迭代器耗尽后通常不能复用;容器的 __iter__ 应返回新迭代器。不要手动捕获生成器内部意外出现的 StopIteration 来控制业务。

官方概念
含 yield 的函数返回生成器,每次恢复时从上次暂停处继续;yield from 把产出委托给另一个可迭代对象,适合组合流水线。
类比记忆
像分批出餐:厨房保留做到哪一步,只在客人需要时继续;委托窗口可以把另一条产线的成品直接转交。
def batches():
yield "准备"
yield from (f"任务-{number}" for number in range(1, 3))
stream = batches()
print(next(stream))
print(list(stream))
运行输出:
准备
['任务-1', '任务-2']
使用边界
生成器中的文件和连接可能跨暂停点保持打开,应设计关闭路径。需要多次遍历、长度或随机访问时,物化容器通常更清晰。

官方概念
装饰器接收可调用对象并返回替代对象,可统一加入鉴权、计时或重试。闭包保存外层配置,functools.wraps 复制名称与文档等元数据。
类比记忆
像在入口加安检门:房间内部流程不变,但每次进入都经过同一检查;门上仍应保留房间原来的名称。
from functools import wraps
def audit(function):
@wraps(function)
def wrapper(*args, **kwargs):
print(f"调用:{function.__name__}")
return function(*args, **kwargs)
return wrapper
@audit
def add(left: int, right: int) -> int:
return left + right
print(add(2, 3), add.__name__)
运行输出:
调用:add
5 add
使用边界
装饰器顺序会改变语义;重试必须限定可重试异常并考虑幂等。包装异步函数时需保持异步调用方式,不能把协程当普通返回值。

官方概念
上下文管理器通过 __enter__、__exit__ 定义作用域;contextlib.contextmanager 可用一个生成器表达获取、交付和释放资源。
类比记忆
像工具借用柜:进入时登记并领用,退出时无论工作成败都归还;调用者只需看到清晰的使用范围。
from contextlib import contextmanager
events = []
@contextmanager
def resource():
events.append("打开")
try:
yield "连接"
finally:
events.append("关闭")
with resource() as value:
events.append(f"使用{value}")
print(events)
运行输出:
['打开', '使用连接', '关闭']
使用边界
若 __exit__ 返回真值会抑制异常,必须谨慎且可解释。多个动态资源可用 ExitStack 统一管理,异步资源则使用 async with。

官方概念
实现 __get__、__set__ 或 __delete__ 的对象参与属性访问;元类创建类对象,可执行注册和结构校验。两者都属于框架层协议。
类比记忆
描述符像每个房间共用的门禁规则,元类像建筑验收规范;住户只看到房间,但入口和建造阶段已有统一约束。
class Positive:
def __set_name__(self, owner, name):
self.storage = f"_{name}"
def __get__(self, instance, owner):
return self if instance is None else getattr(instance, self.storage)
def __set__(self, instance, value):
if value <= 0:
raise ValueError("必须为正数")
setattr(instance, self.storage, value)
class Order:
quantity = Positive()
order = Order()
order.quantity = 3
print(order.quantity)
运行输出:
3
使用边界
业务校验优先考虑普通函数、属性或数据模型;只有大量类共享协议时再引入描述符或元类,否则隐藏控制流会增加维护成本。

官方概念
海象运算符 := 在表达式中绑定值;functools 提供缓存、偏函数和归约工具,itertools 提供高效迭代组件,可组合短小的数据流水线。
类比记忆
像标准积木:先使用尺寸明确的连接件,再考虑自制零件;临时命名只在能减少重复计算时出现。
from itertools import islice
squares = (value * value for value in range(10))
window = list(islice(squares, 3, 7))
large_count = len([
square for value in range(6)
if (square := value * value) > 8
])
print(window, large_count)
运行输出:
[9, 16, 25, 36] 3
使用边界
海象运算符若让条件难读就拆成普通赋值。缓存要求参数可哈希,并会延长对象生命周期;无限迭代器必须搭配终止条件。

事实:生成器在消费时才执行函数体。
因果链:创建成功被当成完成 → 错误延迟到下游 → 资源边界难判断。
影响:接口若标明消费时机,调用方可在正确位置捕获和关闭。
边界:需要立即验证全部输入时应主动物化。

事实:多个装饰器按嵌套顺序包裹同一调用。
因果链:鉴权缓存重试次序含糊 → 安全或幂等语义变化 → 故障难复现。
影响:固定顺序并记录关键事件,可让包装层接受测试。
边界:简单场景直接调用辅助函数更清楚。

事实:Python 语法能力依赖对象协议而非硬编码业务类型。
因果链:到处判断具体类 → 新类型持续修改旧代码 → 耦合扩散。
影响:实现窄协议即可接入迭代、上下文和属性系统。
边界:协议过宽同样会形成隐式基类。

可迭代对象与迭代器:前者能提供迭代器,后者保存一次遍历进度;生成器函数与生成器对象:调用含 yield 的函数才创建对象,函数体在消费时执行;装饰器与包装器:前者是替换过程,后者是返回的可调用对象;属性与描述符:property 是具体描述符工具,描述符协议还能服务多个类。
高级机制以协议封装控制流:迭代器保存进度,生成器延迟计算,装饰器包裹调用,上下文管理器收束资源,描述符统一属性规则。抽象越深,越要说明执行时机、异常路径和资源生命周期。下一块将把这些 Python 能力带入 FastAPI 服务。
