关于 python-project-structure
面向 Python 开发者的项目组织指南,适用于新建或整理现有代码库。内容涵盖模块边界、公共 API、目录布局、导入方式与测试位置。
主要功能
- 01模块内聚与边界
- 02使用 __all__ 声明公共 API
- 03扁平与领域式目录布局
- 04测试文件组织策略
- 05命名与导入约定
适用场景
- 01规划新的 Python 项目
- 02重组现有代码库
- 03创建可复用的 Python 包
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ wshobson/ agents --skill python-project-structure安装后在 Claude Code 中输入/python-project-structure确认已加载。
详细介绍
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 行(具体因复杂度而异)
- 包含因不同原因而变更的类
# Good: Focused files
# user_service.py - User business logic
# user_repository.py - User data access
# user_models.py - User data structures
# Avoid: Kitchen sink files
# user.py - Contains service, repository, models, utilities...
模式 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",
]
# Internal helpers remain private by omission
# from .internal_helpers import _validate_input # Not exported
模式 3:扁平目录结构
优先减少嵌套。过深的层级会让导入变得冗长,让导航变得困难。
# Preferred: Flat structure
project/
├── api/
│ ├── routes.py
│ └── middleware.py
├── services/
│ ├── user_service.py
│ └── order_service.py
├── models/
│ ├── user.py
│ └── order.py
└── utils/
└── validation.py
# Avoid: Deep nesting
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 - A library for doing useful things."""
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 handlers, request/response
│ ├── routes/
│ └── middleware/
├── services/ # Business logic
├── repositories/ # Data access
├── models/ # Domain entities
├── schemas/ # API schemas (Pydantic)
└── config/ # Configuration
每一层只应依赖其下方的层,绝不依赖上方的层。
模式 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中
导入风格
使用绝对导入,以获得清晰性和可靠性:
# Preferred: Absolute imports
from myproject.services import UserService
from myproject.models import User
# Avoid: Relative imports
from ..services import UserService
from . import models
当模块被移动或重新组织时,相对导入可能会失效。
最佳实践总结
- 保持文件聚焦 - 每个文件一个概念,在 300-500 行时考虑拆分(具体因复杂度而异)
- 显式定义
__all__- 让公共接口清晰明了 - 优先采用扁平结构 - 只有存在真正的子领域时才增加深度
- 使用绝对导入 - 更可靠、更清晰
- 保持一致 - 在整个项目中统一应用模式
- 让名称匹配内容 - 文件名应描述其用途
- 分离关注点 - 保持层次分明,依赖只朝一个方向流动
- 记录你的结构 - 包含一个说明组织方式的 README
评论
支持 Markdown