Python项目结构规范_模块边界设计解析【教程】

Python项目结构规范的核心在于以业务能力而非技术分层划分模块,如orders/、payments/等高内聚子包,封装完整能力闭环;跨包通信需通过明确定义接口或事件;公共模块须收敛且文档清晰;入口适配层(如adapters/)仅负责协议转换,不包含业务逻辑;依赖流向必须单向,确保责任清晰与变化隔离。

Python项目结构规范的核心在于模块边界设计是否清晰——它直接决定代码能否长期维护、团队协作是否顺畅、新功能是否容易扩展。

模块划分要以“业务能力”为单位,而非技术分层

很多项目习惯按 models/views/utils/ 这类技术角色切分目录,结果导致一个业务逻辑(比如“用户下单”)散落在五六个模块里,修改时需跳转多次。更合理的方式是按高内聚的业务域组织:

  • 每个子包对应一个明确的业务能力,例如 orders/payments/notifications/
  • 包内封装完整的能力闭环:数据模型、核心逻辑、外部适配(如API调用)、内部事件等都放在该包下
  • 跨包通信只通过明确定义的接口或事件,避免直接导入对方内部函数或类

公共模块要收敛,禁止“到处放工具函数”

常见反模式是 utils.py 越来越大,最后变成“什么都能塞”的垃圾场。正确做法是:

  • 优先把通用逻辑下沉到领域包内部,比如 orders/utils.py 只服务订单逻辑
  • 真正跨领域的抽象才放入顶层 common/core/,且必须附带清晰文档说明用途和约束
  • 拒绝“万能参数”函数,例如 format_data(data, type='json', method='default', ...) ——这种函数本质是边界模糊的信号

入口与适配层要显式隔离,不污染领域逻辑

HTTP接口、命令行、定时任务、消息队列消费者等,都属于“外部交互适配器”,它们应当:

  • 单独成包,如 adapters/http/adapters/cli/adapters/kafka/
  • 只负责协议转换和输入校验,把原始请求转成领域可理解的结构体(DTO),再调用领域服务
  • 绝不包含业务规则判断,比如“如果用户VIP则折扣8折”这类逻辑必须在 orders/ 包内实现,而非写在 FastAPI 的路由函数里

依赖流向必须单向:外层 → 内层,禁止反向穿透

可通过工具(如 pydepsarchi)检查模块依赖图。健康结构应满足:

  • adapters/ 可导入 orders/common/,但不能反过来
  • orders/ 可导入 common/,但不可导入 adapters/ 或其他业务包(除非通过事件总线或抽象协议)
  • common/ 不得依赖任何业务包,否则就不是“通用”,而是“耦合残留”
模块边界的本质不是文件怎么放,而是责任是否清晰、变化是否隔离、协作是否无歧义。结构定型后,多数重构成本会大幅下降。