python-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePython Patterns
Python开发模式
Python development principles and decision-making for 2025. Learn to THINK, not memorize patterns.
2025年Python开发原则与决策制定。 学会思考,而非死记模式。
⚠️ How to Use This Skill
⚠️ 如何使用本技能
This skill teaches decision-making principles, not fixed code to copy.
- ASK user for framework preference when unclear
- Choose async vs sync based on CONTEXT
- Don't default to same framework every time
本技能传授决策原则,而非可供复制的固定代码。
- 当用户需求不明确时,询问其框架偏好
- 根据业务场景选择异步或同步方案
- 不要每次都默认使用同一框架
1. Framework Selection (2025)
1. 2025年框架选择
Decision Tree
决策树
What are you building?
│
├── API-first / Microservices
│ └── FastAPI (async, modern, fast)
│
├── Full-stack web / CMS / Admin
│ └── Django (batteries-included)
│
├── Simple / Script / Learning
│ └── Flask (minimal, flexible)
│
├── AI/ML API serving
│ └── FastAPI (Pydantic, async, uvicorn)
│
└── Background workers
└── Celery + any framework你要构建什么类型的项目?
│
├── API优先 / 微服务
│ └── FastAPI(异步、现代化、高性能)
│
├── 全栈网站 / CMS / 后台管理系统
│ └── Django(开箱即用)
│
├── 简单脚本 / 学习项目
│ └── Flask(轻量、灵活)
│
├── AI/ML API部署
│ └── FastAPI(搭配Pydantic、异步、uvicorn)
│
└── 后台任务
└── Celery + 任意框架Comparison Principles
对比原则
| Factor | FastAPI | Django | Flask |
|---|---|---|---|
| Best for | APIs, microservices | Full-stack, CMS | Simple, learning |
| Async | Native | Django 5.0+ | Via extensions |
| Admin | Manual | Built-in | Via extensions |
| ORM | Choose your own | Django ORM | Choose your own |
| Learning curve | Low | Medium | Low |
| 考量因素 | FastAPI | Django | Flask |
|---|---|---|---|
| 适用场景 | API、微服务 | 全栈、CMS | 简单项目、学习 |
| 异步支持 | 原生支持 | Django 5.0+支持 | 通过扩展实现 |
| 后台管理界面 | 需手动搭建 | 内置 | 通过扩展实现 |
| ORM | 可自主选择 | Django ORM | 可自主选择 |
| 学习曲线 | 低 | 中等 | 低 |
Selection Questions to Ask:
选择时需询问的问题:
- Is this API-only or full-stack?
- Need admin interface?
- Team familiar with async?
- Existing infrastructure?
- 是纯API项目还是全栈项目?
- 是否需要后台管理界面?
- 团队熟悉异步开发吗?
- 现有基础设施是什么?
2. Async vs Sync Decision
2. 异步与同步决策
When to Use Async
何时使用异步
async def is better when:
├── I/O-bound operations (database, HTTP, file)
├── Many concurrent connections
├── Real-time features
├── Microservices communication
└── FastAPI/Starlette/Django ASGI
def (sync) is better when:
├── CPU-bound operations
├── Simple scripts
├── Legacy codebase
├── Team unfamiliar with async
└── Blocking libraries (no async version)优先使用async def的场景:
├── I/O密集型操作(数据库、HTTP请求、文件操作)
├── 高并发连接场景
├── 实时功能
├── 微服务间通信
├── FastAPI/Starlette/Django ASGI部署
优先使用def(同步)的场景:
├── CPU密集型操作
├── 简单脚本
├── 遗留代码库
├── 团队不熟悉异步开发
├── 使用无异步版本的阻塞库The Golden Rule
黄金准则
I/O-bound → async (waiting for external)
CPU-bound → sync + multiprocessing (computing)
Don't:
├── Mix sync and async carelessly
├── Use sync libraries in async code
└── Force async for CPU workI/O密集型 → 异步(等待外部资源)
CPU密集型 → 同步+多进程(计算任务)
禁止:
├── 随意混合异步与同步代码
├── 在异步代码中使用同步库
├── 强制为CPU密集型任务使用异步Async Library Selection
异步库选择
| Need | Async Library |
|---|---|
| HTTP client | httpx |
| PostgreSQL | asyncpg |
| Redis | aioredis / redis-py async |
| File I/O | aiofiles |
| Database ORM | SQLAlchemy 2.0 async, Tortoise |
| 需求 | 异步库 |
|---|---|
| HTTP客户端 | httpx |
| PostgreSQL | asyncpg |
| Redis | aioredis / redis-py async |
| 文件I/O | aiofiles |
| 数据库ORM | SQLAlchemy 2.0 async, Tortoise |
3. Type Hints Strategy
3. 类型提示策略
When to Type
何时使用类型提示
Always type:
├── Function parameters
├── Return types
├── Class attributes
├── Public APIs
Can skip:
├── Local variables (let inference work)
├── One-off scripts
├── Tests (usually)必须添加类型提示的场景:
├── 函数参数
├── 返回值类型
├── 类属性
├── 公共API
可跳过的场景:
├── 局部变量(让类型推断自动处理)
├── 一次性脚本
├── 测试代码(通常情况下)Common Type Patterns
常见类型模式
python
undefinedpython
undefinedThese are patterns, understand them:
这些是模式,理解其原理:
Optional → might be None
Optional → 可能为None
from typing import Optional
def find_user(id: int) -> Optional[User]: ...
from typing import Optional
def find_user(id: int) -> Optional[User]: ...
Union → one of multiple types
Union → 多种类型之一
def process(data: str | dict) -> None: ...
def process(data: str | dict) -> None: ...
Generic collections
泛型集合
def get_items() -> list[Item]: ...
def get_mapping() -> dict[str, int]: ...
def get_items() -> list[Item]: ...
def get_mapping() -> dict[str, int]: ...
Callable
Callable
from typing import Callable
def apply(fn: Callable[[int], str]) -> str: ...
undefinedfrom typing import Callable
def apply(fn: Callable[[int], str]) -> str: ...
undefinedPydantic for Validation
使用Pydantic进行验证
When to use Pydantic:
├── API request/response models
├── Configuration/settings
├── Data validation
├── Serialization
Benefits:
├── Runtime validation
├── Auto-generated JSON schema
├── Works with FastAPI natively
└── Clear error messages何时使用Pydantic:
├── API请求/响应模型
├── 配置/设置
├── 数据验证
├── 序列化
优势:
├── 运行时验证
├── 自动生成JSON Schema
├── 与FastAPI原生集成
├── 清晰的错误提示4. Project Structure Principles
4. 项目结构原则
Structure Selection
结构选择
Small project / Script:
├── main.py
├── utils.py
└── requirements.txt
Medium API:
├── app/
│ ├── __init__.py
│ ├── main.py
│ ├── models/
│ ├── routes/
│ ├── services/
│ └── schemas/
├── tests/
└── pyproject.toml
Large application:
├── src/
│ └── myapp/
│ ├── core/
│ ├── api/
│ ├── services/
│ ├── models/
│ └── ...
├── tests/
└── pyproject.toml小型项目 / 脚本:
├── main.py
├── utils.py
└── requirements.txt
中型API项目:
├── app/
│ ├── __init__.py
│ ├── main.py
│ ├── models/
│ ├── routes/
│ ├── services/
│ └── schemas/
├── tests/
└── pyproject.toml
大型应用:
├── src/
│ └── myapp/
│ ├── core/
│ ├── api/
│ ├── services/
│ ├── models/
│ └── ...
├── tests/
└── pyproject.tomlFastAPI Structure Principles
FastAPI结构原则
Organize by feature or layer:
By layer:
├── routes/ (API endpoints)
├── services/ (business logic)
├── models/ (database models)
├── schemas/ (Pydantic models)
└── dependencies/ (shared deps)
By feature:
├── users/
│ ├── routes.py
│ ├── service.py
│ └── schemas.py
└── products/
└── ...按功能或分层组织:
分层组织:
├── routes/(API端点)
├── services/(业务逻辑)
├── models/(数据库模型)
├── schemas/(Pydantic模型)
└── dependencies/(共享依赖)
按功能组织:
├── users/
│ ├── routes.py
│ ├── service.py
│ └── schemas.py
└── products/
└── ...5. Django Principles (2025)
5. Django开发原则(2025)
Django Async (Django 5.0+)
Django异步支持(Django 5.0+)
Django supports async:
├── Async views
├── Async middleware
├── Async ORM (limited)
└── ASGI deployment
When to use async in Django:
├── External API calls
├── WebSocket (Channels)
├── High-concurrency views
└── Background task triggeringDjango支持的异步特性:
├── 异步视图
├── 异步中间件
├── 异步ORM(有限支持)
├── ASGI部署
在Django中使用异步的场景:
├── 外部API调用
├── WebSocket(搭配Channels)
├── 高并发视图
├── 触发后台任务Django Best Practices
Django最佳实践
Model design:
├── Fat models, thin views
├── Use managers for common queries
├── Abstract base classes for shared fields
Views:
├── Class-based for complex CRUD
├── Function-based for simple endpoints
├── Use viewsets with DRF
Queries:
├── select_related() for FKs
├── prefetch_related() for M2M
├── Avoid N+1 queries
└── Use .only() for specific fields模型设计:
├── 胖模型,瘦视图
├── 使用管理器处理通用查询
├── 为共享字段使用抽象基类
视图:
├── 复杂CRUD使用类视图
├── 简单端点使用函数视图
├── 搭配DRF使用视图集
查询优化:
├── 外键查询使用select_related()
├── 多对多查询使用prefetch_related()
├── 避免N+1查询问题
├── 使用.only()获取特定字段6. FastAPI Principles
6. FastAPI开发原则
async def vs def in FastAPI
FastAPI中的async def vs def
Use async def when:
├── Using async database drivers
├── Making async HTTP calls
├── I/O-bound operations
└── Want to handle concurrency
Use def when:
├── Blocking operations
├── Sync database drivers
├── CPU-bound work
└── FastAPI runs in threadpool automatically使用async def的场景:
├── 使用异步数据库驱动
├── 发起异步HTTP请求
├── I/O密集型操作
├── 需要处理高并发
使用def的场景:
├── 阻塞操作
├── 使用同步数据库驱动
├── CPU密集型任务
├── FastAPI会自动在线程池中运行Dependency Injection
依赖注入
Use dependencies for:
├── Database sessions
├── Current user / Auth
├── Configuration
├── Shared resources
Benefits:
├── Testability (mock dependencies)
├── Clean separation
├── Automatic cleanup (yield)依赖注入的适用场景:
├── 数据库会话
├── 当前用户/身份验证
├── 配置信息
├── 共享资源
优势:
├── 可测试性(模拟依赖)
├── 清晰的关注点分离
├── 自动清理(使用yield)Pydantic v2 Integration
Pydantic v2集成
python
undefinedpython
undefinedFastAPI + Pydantic are tightly integrated:
FastAPI与Pydantic深度集成:
Request validation
请求验证
@app.post("/users")
async def create(user: UserCreate) -> UserResponse:
# user is already validated
...
@app.post("/users")
async def create(user: UserCreate) -> UserResponse:
# user已完成验证
...
Response serialization
响应序列化
Return type becomes response schema
返回类型自动作为响应Schema
---
---7. Background Tasks
7. 后台任务
Selection Guide
方案选择指南
| Solution | Best For |
|---|---|
| BackgroundTasks | Simple, in-process tasks |
| Celery | Distributed, complex workflows |
| ARQ | Async, Redis-based |
| RQ | Simple Redis queue |
| Dramatiq | Actor-based, simpler than Celery |
| 解决方案 | 适用场景 |
|---|---|
| BackgroundTasks | 简单、进程内任务 |
| Celery | 分布式、复杂工作流 |
| ARQ | 异步、基于Redis |
| RQ | 简单Redis队列 |
| Dramatiq | 基于Actor模型,比Celery更简洁 |
When to Use Each
各方案的适用场景
FastAPI BackgroundTasks:
├── Quick operations
├── No persistence needed
├── Fire-and-forget
└── Same process
Celery/ARQ:
├── Long-running tasks
├── Need retry logic
├── Distributed workers
├── Persistent queue
└── Complex workflowsFastAPI BackgroundTasks:
├── 快速操作
├── 无需持久化
├── 即发即弃
├── 同进程内执行
Celery/ARQ:
├── 长时间运行的任务
├── 需要重试逻辑
├── 分布式工作节点
├── 持久化队列
├── 复杂工作流8. Error Handling Principles
8. 错误处理原则
Exception Strategy
异常策略
In FastAPI:
├── Create custom exception classes
├── Register exception handlers
├── Return consistent error format
└── Log without exposing internals
Pattern:
├── Raise domain exceptions in services
├── Catch and transform in handlers
└── Client gets clean error responseFastAPI中的错误处理:
├── 自定义异常类
├── 注册异常处理器
├── 返回统一的错误格式
├── 记录日志但不暴露内部细节
模式:
├── 在服务层抛出领域异常
├── 在处理器中捕获并转换
├── 向客户端返回清晰的错误响应Error Response Philosophy
错误响应设计原则
Include:
├── Error code (programmatic)
├── Message (human readable)
├── Details (field-level when applicable)
└── NOT stack traces (security)需包含:
├── 错误码(供程序识别)
├── 错误信息(人类可读)
├── 详细信息(适用时的字段级错误)
└—— 禁止返回堆栈跟踪(安全考虑)9. Testing Principles
9. 测试原则
Testing Strategy
测试策略
| Type | Purpose | Tools |
|---|---|---|
| Unit | Business logic | pytest |
| Integration | API endpoints | pytest + httpx/TestClient |
| E2E | Full workflows | pytest + DB |
| 测试类型 | 目的 | 工具 |
|---|---|---|
| 单元测试 | 测试业务逻辑 | pytest |
| 集成测试 | 测试API端点 | pytest + httpx/TestClient |
| 端到端测试 | 测试完整工作流 | pytest + 数据库 |
Async Testing
异步测试
python
undefinedpython
undefinedUse pytest-asyncio for async tests
使用pytest-asyncio进行异步测试
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_endpoint():
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.get("/users")
assert response.status_code == 200
undefinedimport pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_endpoint():
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.get("/users")
assert response.status_code == 200
undefinedFixtures Strategy
Fixture策略
Common fixtures:
├── db_session → Database connection
├── client → Test client
├── authenticated_user → User with token
└── sample_data → Test data setup常用Fixture:
├── db_session → 数据库连接
├── client → 测试客户端
├── authenticated_user → 带令牌的用户
└── sample_data → 测试数据准备10. Decision Checklist
10. 决策检查清单
Before implementing:
- Asked user about framework preference?
- Chosen framework for THIS context? (not just default)
- Decided async vs sync?
- Planned type hint strategy?
- Defined project structure?
- Planned error handling?
- Considered background tasks?
在开始实现前:
- 询问过用户的框架偏好吗?
- 是否根据当前场景选择了合适的框架?(而非默认框架)
- 确定了异步还是同步方案?
- 规划了类型提示策略?
- 定义了项目结构?
- 规划了错误处理方案?
- 考虑了后台任务需求?
11. Anti-Patterns to Avoid
11. 需避免的反模式
❌ DON'T:
❌ 禁止:
- Default to Django for simple APIs (FastAPI may be better)
- Use sync libraries in async code
- Skip type hints for public APIs
- Put business logic in routes/views
- Ignore N+1 queries
- Mix async and sync carelessly
- 简单API项目默认使用Django(FastAPI可能更合适)
- 在异步代码中使用同步库
- 公共API跳过类型提示
- 将业务逻辑写在路由/视图中
- 忽略N+1查询问题
- 随意混合异步与同步代码
✅ DO:
✅ 推荐:
- Choose framework based on context
- Ask about async requirements
- Use Pydantic for validation
- Separate concerns (routes → services → repos)
- Test critical paths
Remember: Python patterns are about decision-making for YOUR specific context. Don't copy code—think about what serves your application best.
- 根据场景选择框架
- 询问异步需求
- 使用Pydantic进行验证
- 关注点分离(路由→服务→仓库)
- 测试关键路径
谨记:Python开发模式是针对你的特定场景制定决策。不要复制代码——思考什么最适合你的应用。