责任链模式在Python中通过显式传递处理器和条件判断实现,各处理器实现统一handle()接口,以next_handler参数动态组装链,避免硬编码依赖,支持运行时配置与灵活扩展。

责任链模式在 Python 中不是靠某个内置函数实现的,而是靠对象间显式传递和条件判断来完成;强行套用装饰器或抽象基类反而容易让逻辑变重、调试变难。
用 handle() 方法串联处理器是最轻量的做法
每个处理器实现统一的 handle() 接口,内部决定是否处理请求、是否继续传递。不依赖第三方库,也不需要定义抽象类——Python 的鸭子类型足够支撑这种松耦合。
常见错误是让处理器自己创建下一个处理器实例(比如在 __init__ 里硬编码 self.next_handler = NextHandler()),这会破坏链的可配置性。
- 把下一个处理器作为参数传入,而不是在类内初始化
- 允许链末端为
None,并在handle()中显式判空,避免AttributeError - 返回值统一:处理了就返回结果(如
dict或str),不处理就调用self.next_handler.handle(...)
class AuthHandler:
def __init__(self, next_handler=None):
self.next_handler = next_handler
<pre class="brush:php;toolbar:false;">def handle(self, request):
if 'token' not in request:
return {'error': 'missing token'}
if not request['token'].startswith('Bearer '):
return {'error': 'invalid token format'}
return self.next_handler.handle(request) if self.next_handler else {'status': 'ok'}class RateLimitHandler: def init(self, next_handler=None): self.next_handler = next_handler
def handle(self, request):
# 简单计数示意
if request.get('call_count', 0) > 5:
return {'error': 'rate limit exceeded'}
return self.next_handler.handle(request) if self.next_handler else {'status': 'ok'}
链的组装必须在运行时动态完成,不能写死
硬编码链顺序(比如 AuthHandler(RateLimitHandler(LoggerHandler())))会让单元测试困难,也难以根据环境切换行为(如开发环境跳过鉴权)。
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
典型使用场景是 Web 请求预处理、日志分级、异步任务拦截等——这些场景下,链的构成往往取决于配置或上下文。
- 用列表收集处理器,再用循环或
functools.reduce连接 - 支持按条件插入/跳过某环节(例如
if debug_mode: handlers.insert(1, DebugHandler())) - 避免在链中修改原始请求对象,除非明确约定;否则下游可能读到被意外篡改的数据
handlers = [AuthHandler(), RateLimitHandler(), LoggerHandler()]
# 从右往左组装:Logger → RateLimit → Auth
chain = None
for h in reversed(handlers):
h.next_handler = chain
chain = h
result = chain.handle({'token': 'Bearer abc123', 'call_count': 3})
别忽略异常穿透和短路退出的细节
责任链不是“所有处理器都必须执行一遍”,而是“找到第一个能处理的就停”。但实际中常遇到两类问题:一是某个处理器抛异常没被捕获,导致整条链中断;二是本该终止却误调了 next_handler,引发 None.handle() 报错。
- 每个
handle()方法应只负责自己的逻辑,不主动捕获其他处理器的异常(除非有兜底策略) - 在调用
self.next_handler.handle(...)前,务必检查self.next_handler is not None - 如果某环节必须保证执行(如审计日志),就不要放进链里,而是在链外单独调用
真正麻烦的不是写几个 handle(),而是确定谁该决定“是否继续”——这个判断逻辑一旦分散在各处,很快就会变成隐式契约。建议把流转规则收口到一个薄薄的 dispatch() 函数里,哪怕只是多包一层。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










