name: python-project-structure description: Python 项目组织、模块架构和公共 API 设计。在设置新项目、组织模块、使用 all 定义公共接口或规划目录布局时使用。
Python 项目结构与模块架构
设计组织良好的 Python 项目,具有清晰的模块边界、明确的公共接口和可维护的目录结构。良好的组织使代码易于发现,变更可预测。
何时使用此技能
- 从零开始一个新 Python 项目
- 为清晰性重组现有代码库
- 使用
__all__定义模块公共 API - 在扁平化和嵌套目录结构之间做决定
- 确定测试文件放置策略
- 创建可重用的库包
核心概念
1. 模块内聚
将一起变化的相关代码分组。一个模块应有一个单一、清晰的目的。
2. 明确接口
使用 __all__ 定义公共内容。未列出的内容都是内部实现细节。
3. 扁平层次
优先使用浅目录结构。仅在有真正子域时才增加深度。
4. 一致惯例
在整个项目中一致应用命名和组织模式。
快速开始
myproject/
├── src/
│ └── myproject/
│ ├── __init__.py
│ ├── services/
│ ├── models/
│ └── api/
├── tests/
├── pyproject.toml
└── README.md
基本模式
模式 1:每个文件一个概念
每个文件应专注于一个概念或紧密相关的函数集。考虑拆分文件当:
- 处理多个不相关的职责
- 文件超过 300-500 行(根据复杂性变化)
- 包含因不同原因而变化的类
# 好:专注的文件
# user_service.py - 用户业务逻辑
# user_repository.py - 用户数据访问
# user_models.py - 用户数据结构
# 避免:大杂烩文件
# user.py - 包含服务、存储库、模型、工具...
模式 2:使用 __all__ 明确公共 API
为每个模块定义公共接口。未列出的成员是内部实现细节。
# mypackage/services/__init__.py
from .user_service import UserService
from .order_service import OrderService
from .exceptions import ServiceError, ValidationError
__all__ = [
"UserService",
"OrderService",
"ServiceError",
"ValidationError",
]
# 内部助手保持私有
# from .internal_helpers import _validate_input # 不导出
模式 3:扁平目录结构
优先最小化嵌套。深层次结构使导入冗长且导航困难。
# 推荐:扁平结构
project/
├── api/
│ ├── routes.py
│ └── middleware.py
├── services/
│ ├── user_service.py
│ └── order_service.py
├── models/
│ ├── user.py
│ └── order.py
└── utils/
└── validation.py
# 避免:深度嵌套
project/core/internal/services/impl/user/
仅当有真正需要隔离的子域时才添加子包。
模式 4:测试文件组织
选择一种方法并在整个项目中一致应用。
选项 A:并置测试
src/
├── user_service.py
├── test_user_service.py
├── order_service.py
└── test_order_service.py
好处:测试位于它们验证的代码旁边。易于查看覆盖缺口。
选项 B:并行测试目录
src/
├── services/
│ ├── user_service.py
│ └── order_service.py
tests/
├── services/
│ ├── test_user_service.py
│ └── test_order_service.py
好处:生产代码和测试代码清晰分离。适用于大型项目。
高级模式
模式 5:包初始化
使用 __init__.py 为包用户提供干净的公共接口。
# mypackage/__init__.py
"""MyPackage - 一个用于做有用事情的库。"""
from .core import MainClass, HelperClass
from .exceptions import PackageError, ConfigError
from .config import Settings
__all__ = [
"MainClass",
"HelperClass",
"PackageError",
"ConfigError",
"Settings",
]
__version__ = "1.0.0"
用户可以直接从包中导入:
from mypackage import MainClass, Settings
模式 6:分层架构
按架构层组织代码,以实现清晰的关注点分离。
myapp/
├── api/ # HTTP 处理器、请求/响应
│ ├── routes/
│ └── middleware/
├── services/ # 业务逻辑
├── repositories/ # 数据访问
├── models/ # 领域实体
├── schemas/ # API 模式(Pydantic)
└── config/ # 配置
每层应仅依赖于其下的层,而不是其上的层。
模式 7:领域驱动结构
对于复杂应用,按业务领域而非技术层组织。
ecommerce/
├── users/
│ ├── models.py
│ ├── services.py
│ ├── repository.py
│ └── api.py
├── orders/
│ ├── models.py
│ ├── services.py
│ ├── repository.py
│ └── api.py
└── shared/
├── database.py
└── exceptions.py
文件和模块命名
惯例
- 对所有文件和模块名使用
snake_case:user_repository.py - 避免模糊含义的缩写:
user_repository.py而不是usr_repo.py - 类名与文件名匹配:
UserService在user_service.py中
导入风格
为清晰性和可靠性使用绝对导入:
# 推荐:绝对导入
from myproject.services import UserService
from myproject.models import User
# 避免:相对导入
from ..services import UserService
from . import models
相对导入在模块移动或重组时可能出错。
最佳实践总结
- 保持文件专注 - 每个文件一个概念,考虑在 300-500 行时拆分(根据复杂性变化)
- 明确定义
__all__- 使公共接口清晰 - 优先扁平结构 - 仅当有真正子域时才增加深度
- 使用绝对导入 - 更可靠和清晰
- 保持一致 - 在整个项目中一致应用模式
- 名称与内容匹配 - 文件名应描述其目的
- 分离关注点 - 保持各层清晰,依赖单向流动
- 记录你的结构 - 包含一个 README 解释组织方式