Python中实现生成器级联分流的核心是yield from而非yield*,它支持状态感知路由、惰性求值与零拷贝;通过validator_stream打标、route_by_tag按pkt["route"]委托给不同处理生成器,结合外置配置与Pathway可构建端到端流式清洗管道。

Python 中没有 yield* 语法(那是 JavaScript 的写法),你实际想用的是 yield from —— 它才是 Python 实现生成器级联、状态感知分流的核心机制。关键不在于“语法炫技”,而在于如何让上游处理结果(比如某行是否含异常、是否通过校验)实时决定下游走哪条清洗路径,且全程保持惰性、零拷贝、内存可控。
用 yield from 实现带状态的条件分流
核心思路:把每个清洗阶段封装为接受“上下文流”和“控制信号”的生成器,用 yield from 委托给不同子生成器,由前置节点产出的元数据(如 {"status": "valid", "route": "enrich"})驱动路由选择。
- 不靠 if/else 拼接逻辑块,而是让每个分支本身就是一个可复用、可测试的生成器
- 上游只产出带标签的数据包(
dict或自定义NamedTuple),下游按packet.route分发 -
yield from天然支持异常透传和send()双向通信,便于在运行中动态调整策略
典型场景:根据校验结果分发到不同修复通道
例如,手机号列校验失败时走人工复核队列,金额格式错误时自动清洗,其余正常数据直通输出:
def validator_stream(packets):
for pkt in packets:
phone_ok = bool(re.fullmatch(r"^1[3-9]\d{9}$", pkt.get("phone", "")))
amount_ok = isinstance(pkt.get("amount"), (int, float)) and pkt["amount"] >= 0
if not phone_ok and not amount_ok:
pkt["route"] = "manual_review"
elif not amount_ok:
pkt["route"] = "clean_amount"
else:
pkt["route"] = "pass_through"
yield pkt
<p>def route_by_tag(packets):
for pkt in packets:
if pkt["route"] == "manual_review":
yield from manual_review_handler(pkt)
elif pkt["route"] == "clean_amount":
yield from clean_amount_handler(pkt)
else:
yield from pass_through_handler(pkt)</p><p>def manual_review_handler(pkt):
pkt["review_flag"] = "pending"
yield pkt # 发往审核队列(如 Kafka topic)</p><p>def clean_amount_handler(pkt):
raw = str(pkt["amount"])
cleaned = re.sub(r"[^\d.-]", "", raw)
try:
pkt["amount"] = float(cleaned) if cleaned else 0.0
except ValueError:
pkt["amount"] = 0.0
yield pkt
整个链路只需 yield from route_by_tag(validator_stream(raw_packets)) 启动,无中间 DataFrame、无全量缓存。
结合配置实现运行时策略切换
把路由规则外置到 YAML 或数据库,让 route_by_tag 查表决定委托目标,无需改代码即可上线新清洗策略:
- 配置项示例:
{"rules": [{"cond": "pkt['amount'] < 0", "to": "neg_amount_fix"}, ...]} - 生成器内用
eval()(沙箱环境)或预编译ast.Expression安全执行条件判断 - 每次路由决策仍由
yield from承载,保证流式语义不变
与 Pathway 等流引擎协同的关键点
若后端对接 Pathway 这类增量引擎,yield from 管道适合作为其数据源层(source connector):
- 将原始 Kafka 消息流喂入你的生成器管道,做轻量预筛、打标、拆包
- 再把带
route标签的流交给pw.io.python.read(..., format="json") - Pathway 内部按
pw.this.route做.filter()分支,实现真正端到端的语义分流
这样既保留 Python 层灵活的文本/规则处理能力,又享受底层 Rust 引擎的乱序重算、exactly-once 保障。

















