如何用原生Python实现FastAPI风格的Depends()依赖注入(无外部包)
手动实现类似FastAPI Depends的依赖注入功能
实现思路
- 识别依赖标记:通过函数参数的默认值(
Depends实例),定位需要注入的依赖函数 - 递归解析依赖链:如果依赖函数自身也带有
Depends参数,递归解析所有层级的依赖,保证执行顺序符合依赖关系 - 执行依赖并收集结果:按依赖顺序依次执行所有依赖函数,把结果整理后注入到目标函数的对应参数中
- 可选扩展:可以添加依赖复用策略,比如同一请求内复用依赖实例(单例),或每次调用都重新创建实例
完整代码示例
from typing import Callable, Optional, Any import inspect class Depends: def __init__(self, dependency: Optional[Callable[..., Any]] = None): self.dependency = dependency # 核心依赖解析器 def resolve_deps(func: Callable) -> dict: resolved = {} # 获取函数的参数签名信息 sig = inspect.signature(func) for param_name, param in sig.parameters.items(): # 判断参数默认值是否为Depends实例 if isinstance(param.default, Depends): dep_func = param.default.dependency if not dep_func: raise ValueError(f"参数{param_name}的依赖函数不能为空") # 递归解析当前依赖函数的依赖 dep_results = resolve_deps(dep_func) # 执行依赖函数并保存结果 resolved[param_name] = dep_func(**dep_results) return resolved # ------------------- 测试用例 ------------------- def get_db(): print("[执行] 创建数据库连接") return "数据库连接实例" def get_token(): print("[执行] 从请求中提取用户token") return "user_abc_123_token" def get_current_user(db=Depends(get_db), token=Depends(get_token)): print(f"[执行] 使用DB: {db} 和 Token: {token} 查询用户信息") return {"user_id": 1001, "username": "张三"} # 使用方式 if __name__ == "__main__": # 解析get_current_user的所有依赖 dependencies = resolve_deps(get_current_user) # 注入依赖并执行目标函数 current_user = get_current_user(**dependencies) print("\n最终获取的用户信息:", current_user)
代码说明
Depends类:仅作为标记类,存储需要注入的目标依赖函数resolve_deps函数:- 通过
inspect.signature获取函数的参数详情 - 遍历参数识别
Depends类型的默认值,递归处理嵌套依赖 - 执行所有依赖函数,收集结果后返回给调用方
- 通过
- 测试用例:模拟了三层调用链,运行后会按依赖顺序执行函数,最终将结果注入到
get_current_user中
内容的提问来源于stack exchange,提问作者Mahbub Rahman
相关产品推荐
相关产品推荐

