mcpField
P
python-project-structure

python-project-structure

github.com/wshobson开发41.9k15.0k 次安装2 周前更新
代码仓库

关于 python-project-structure

面向 Python 开发者的项目组织指南,适用于新建或整理现有代码库。内容涵盖模块边界、公共 API、目录布局、导入方式与测试位置。

主要功能

  1. 01模块内聚与边界
  2. 02使用 __all__ 声明公共 API
  3. 03扁平与领域式目录布局
  4. 04测试文件组织策略
  5. 05命名与导入约定

适用场景

  1. 01规划新的 Python 项目
  2. 02重组现有代码库
  3. 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

当模块被移动或重新组织时,相对导入可能会失效。

最佳实践总结

  1. 保持文件聚焦 - 每个文件一个概念,在 300-500 行时考虑拆分(具体因复杂度而异)
  2. 显式定义 __all__ - 让公共接口清晰明了
  3. 优先采用扁平结构 - 只有存在真正的子领域时才增加深度
  4. 使用绝对导入 - 更可靠、更清晰
  5. 保持一致 - 在整个项目中统一应用模式
  6. 让名称匹配内容 - 文件名应描述其用途
  7. 分离关注点 - 保持层次分明,依赖只朝一个方向流动
  8. 记录你的结构 - 包含一个说明组织方式的 README

评论

支持 Markdown