大型Python项目应按业务域分层,如orders/、products/,每域内设domain/application/infrastructure子包;公共能力抽为shared/;接入层(api/cli)仅作输入输出,业务逻辑全在application层;测试与代码同目录;__init__.py显式声明公共API。

大型Python项目不是把所有代码塞进一个文件夹就完事,关键在于分层清晰、职责明确、易于测试和扩展。包结构设计本质是定义模块间的依赖边界和演进路径。
核心原则:按领域分层,而非技术类型
别用“models/”、“views/”、“utils/”这种纯技术分类方式堆砌目录——它会让业务逻辑四处散落,改一个功能要跳转七八个地方。应该以业务域(Domain)或核心能力为单位组织顶层包。
- 例如电商项目,顶层可设 orders/、products/、payments/,每个包内再按需包含
domain/(实体、值对象、领域服务)、application/(用例、DTO、命令处理)、infrastructure/(数据库适配、第三方API封装) - 公共基础能力(如日志、配置、异常体系)单独抽成 shared/ 或 common/ 包,禁止业务包直接 import 其他业务包的内部模块
- 顶层不放 .py 文件,只保留
__init__.py(可为空)和pyproject.toml相关配置
入口与隔离:main 和 api 层要轻量且无业务逻辑
CLI 命令、Web 接口、定时任务等都属于“接入层”,只负责解析输入、调用 application 层、格式化输出。它们不能持有领域模型,也不能直连数据库。
-
cli/ 下每个命令对应一个独立模块,如
cli/order_create.py,仅初始化命令参数并转发给orders.application.create_order() - api/(如 FastAPI)中路由函数只做数据校验和 DTO 转换,业务动作全部委托给 application 层函数或类方法
- 接入层通过依赖注入容器(如
dependencies.py)获取 service 实例,避免硬编码初始化
测试友好性:每个业务包自带 tests/ 子目录
测试代码必须和被测代码物理相邻,而不是全堆在项目根目录的 tests/ 里。这样重构某个域时,能一眼看到影响范围,并快速运行对应测试。
立即学习“Python免费学习笔记(深入)”;
- 每个
orders/包下建tests/,结构镜像源码:tests/domain/test_order.py、tests/application/test_create_order.py - 单元测试聚焦单个函数或类,用
unittest.mock或pytest-mock替换 infrastructure 依赖(如 mock 数据库 session) - 集成测试放在项目级
tests/integration/,验证跨包协作,例如“下单 → 扣库存 → 发通知”全流程
可维护细节:__init__.py 的公开接口控制
每个包的 __init__.py 是该包对外的“门面”。它不该是自动导入所有子模块的中转站,而应显式声明哪些符号是供外部使用的稳定 API。
-
orders/__init__.py可写:# public APIfrom .application import create_order, cancel_orderfrom .domain import Order, OrderStatus - 隐藏实现细节:不导出
infrastructure/下的类,不导出domain/_validation.py这类私有模块 - 配合
py.typed文件 + 类型注解,让 mypy 和 IDE 精准识别包的公共契约










