chore: import zh skill python-code-style
This commit is contained in:
@@ -0,0 +1,359 @@
|
||||
---
|
||||
name: python-code-style
|
||||
description: Python 代码风格、代码检查、格式化、命名规范与文档标准。适用于编写新代码、审查风格、配置代码检查工具、编写文档字符串或制定项目标准。
|
||||
---
|
||||
|
||||
# Python 代码风格与文档
|
||||
|
||||
一致的代码风格和清晰的文档可以让代码库更易于维护和协作。本技能涵盖现代 Python 工具链、命名规范与文档标准。
|
||||
|
||||
## 何时使用本技能
|
||||
|
||||
- 为新项目配置代码检查和格式化工具
|
||||
- 编写或审查文档字符串
|
||||
- 制定团队编码标准
|
||||
- 配置 ruff、mypy 或 pyright
|
||||
- 审查代码的风格一致性
|
||||
- 创建项目文档
|
||||
|
||||
## 核心概念
|
||||
|
||||
### 1. 自动化格式化
|
||||
|
||||
让工具来处理格式争论。一次配置,自动执行。
|
||||
|
||||
### 2. 一致的命名
|
||||
|
||||
遵循 PEP 8 规范,使用有意义且描述清晰的名称。
|
||||
|
||||
### 3. 文档即代码
|
||||
|
||||
文档字符串应与其所描述的代码保持同步维护。
|
||||
|
||||
### 4. 类型注解
|
||||
|
||||
现代 Python 代码中,所有公开 API 都应包含类型提示。
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
# 安装现代工具链
|
||||
pip install ruff mypy
|
||||
|
||||
# 在 pyproject.toml 中配置
|
||||
[tool.ruff]
|
||||
line-length = 120
|
||||
target-version = "py312" # 根据项目的最低 Python 版本调整
|
||||
|
||||
[tool.mypy]
|
||||
strict = true
|
||||
```
|
||||
|
||||
## 基本模式
|
||||
|
||||
### 模式 1:现代 Python 工具链
|
||||
|
||||
使用 `ruff` 作为集代码检查与格式化为一体的一站式工具。它用一个快速工具取代了 flake8、isort 和 black。
|
||||
|
||||
```toml
|
||||
# pyproject.toml
|
||||
[tool.ruff]
|
||||
line-length = 120
|
||||
target-version = "py312" # 根据项目的最低 Python 版本调整
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"E", # pycodestyle 错误
|
||||
"W", # pycodestyle 警告
|
||||
"F", # pyflakes
|
||||
"I", # isort
|
||||
"B", # flake8-bugbear
|
||||
"C4", # flake8-comprehensions
|
||||
"UP", # pyupgrade
|
||||
"SIM", # flake8-simplify
|
||||
]
|
||||
ignore = ["E501"] # 行长度由格式化工具处理
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "double"
|
||||
indent-style = "space"
|
||||
```
|
||||
|
||||
运行方式:
|
||||
|
||||
```bash
|
||||
ruff check --fix . # 代码检查并自动修复
|
||||
ruff format . # 格式化代码
|
||||
```
|
||||
|
||||
### 模式 2:类型检查配置
|
||||
|
||||
为生产代码配置严格模式的类型检查。
|
||||
|
||||
```toml
|
||||
# pyproject.toml
|
||||
[tool.mypy]
|
||||
python_version = "3.12"
|
||||
strict = true
|
||||
warn_return_any = true
|
||||
warn_unused_ignores = true
|
||||
disallow_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "tests.*"
|
||||
disallow_untyped_defs = false
|
||||
```
|
||||
|
||||
备选方案:使用 `pyright` 以获得更快的检查速度。
|
||||
|
||||
```toml
|
||||
[tool.pyright]
|
||||
pythonVersion = "3.12"
|
||||
typeCheckingMode = "strict"
|
||||
```
|
||||
|
||||
### 模式 3:命名规范
|
||||
|
||||
遵循 PEP 8,以清晰性优先于简洁性。
|
||||
|
||||
**文件和模块:**
|
||||
|
||||
```python
|
||||
# 好:描述性的 snake_case
|
||||
user_repository.py
|
||||
order_processing.py
|
||||
http_client.py
|
||||
|
||||
# 避免:缩写
|
||||
usr_repo.py
|
||||
ord_proc.py
|
||||
http_cli.py
|
||||
```
|
||||
|
||||
**类和函数:**
|
||||
|
||||
```python
|
||||
# 类:PascalCase
|
||||
class UserRepository:
|
||||
pass
|
||||
|
||||
class HTTPClientFactory: # 缩写保持大写
|
||||
pass
|
||||
|
||||
# 函数和变量:snake_case
|
||||
def get_user_by_email(email: str) -> User | None:
|
||||
retry_count = 3
|
||||
max_connections = 100
|
||||
```
|
||||
|
||||
**常量:**
|
||||
|
||||
```python
|
||||
# 模块级常量:SCREAMING_SNAKE_CASE
|
||||
MAX_RETRY_ATTEMPTS = 3
|
||||
DEFAULT_TIMEOUT_SECONDS = 30
|
||||
API_BASE_URL = "https://api.example.com"
|
||||
```
|
||||
|
||||
### 模式 4:导入组织
|
||||
|
||||
按一致的顺序分组导入:标准库、第三方库、本地模块。
|
||||
|
||||
```python
|
||||
# 标准库
|
||||
import os
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
# 第三方包
|
||||
import httpx
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import Column
|
||||
|
||||
# 本地导入
|
||||
from myproject.models import User
|
||||
from myproject.services import UserService
|
||||
```
|
||||
|
||||
始终使用绝对导入:
|
||||
|
||||
```python
|
||||
# 推荐
|
||||
from myproject.utils import retry_decorator
|
||||
|
||||
# 避免相对导入
|
||||
from ..utils import retry_decorator
|
||||
```
|
||||
|
||||
## 进阶模式
|
||||
|
||||
### 模式 5:Google 风格的文档字符串
|
||||
|
||||
为所有公开的类、方法和函数编写文档字符串。
|
||||
|
||||
**简单函数:**
|
||||
|
||||
```python
|
||||
def get_user(user_id: str) -> User:
|
||||
"""根据唯一标识符获取用户。"""
|
||||
...
|
||||
```
|
||||
|
||||
**复杂函数:**
|
||||
|
||||
```python
|
||||
def process_batch(
|
||||
items: list[Item],
|
||||
max_workers: int = 4,
|
||||
on_progress: Callable[[int, int], None] | None = None,
|
||||
) -> BatchResult:
|
||||
"""使用工作池并发处理任务。
|
||||
|
||||
使用配置的工作线程数处理批次中的每个任务。
|
||||
可通过可选的回调函数监控处理进度。
|
||||
|
||||
Args:
|
||||
items: 待处理的任务列表。不能为空。
|
||||
max_workers: 最大并发工作线程数。默认为 4。
|
||||
on_progress: 可选回调函数,接收 (已完成数, 总数) 参数。
|
||||
|
||||
Returns:
|
||||
BatchResult,包含处理成功的任务以及失败任务及其对应的异常信息。
|
||||
|
||||
Raises:
|
||||
ValueError: 如果 items 为空。
|
||||
ProcessingError: 如果批次无法处理。
|
||||
|
||||
Example:
|
||||
>>> result = process_batch(items, max_workers=8)
|
||||
>>> print(f"已处理 {len(result.succeeded)} 个任务")
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
**类的文档字符串:**
|
||||
|
||||
```python
|
||||
class UserService:
|
||||
"""用户操作管理服务。
|
||||
|
||||
提供创建、获取、更新和删除用户的方法,
|
||||
并包含适当的验证和错误处理。
|
||||
|
||||
Attributes:
|
||||
repository: 用户持久化的数据访问层。
|
||||
logger: 操作跟踪的日志记录器实例。
|
||||
|
||||
Example:
|
||||
>>> service = UserService(repository, logger)
|
||||
>>> user = service.create_user(CreateUserInput(...))
|
||||
"""
|
||||
|
||||
def __init__(self, repository: UserRepository, logger: Logger) -> None:
|
||||
"""初始化用户服务。
|
||||
|
||||
Args:
|
||||
repository: 用户的数据访问层。
|
||||
logger: 用于跟踪操作的日志记录器。
|
||||
"""
|
||||
self.repository = repository
|
||||
self.logger = logger
|
||||
```
|
||||
|
||||
### 模式 6:行长度与格式化
|
||||
|
||||
对于现代显示器,将行长度设置为 120 个字符,同时保持可读性。
|
||||
|
||||
```python
|
||||
# 好:可读的换行
|
||||
def create_user(
|
||||
email: str,
|
||||
name: str,
|
||||
role: UserRole = UserRole.MEMBER,
|
||||
notify: bool = True,
|
||||
) -> User:
|
||||
...
|
||||
|
||||
# 好:清晰的链式方法调用
|
||||
result = (
|
||||
db.query(User)
|
||||
.filter(User.active == True)
|
||||
.order_by(User.created_at.desc())
|
||||
.limit(10)
|
||||
.all()
|
||||
)
|
||||
|
||||
# 好:格式化长字符串
|
||||
error_message = (
|
||||
f"处理用户 {user_id} 失败:"
|
||||
f"收到状态码 {response.status_code},"
|
||||
f"响应体为 {response.text[:100]}"
|
||||
)
|
||||
```
|
||||
|
||||
### 模式 7:项目文档
|
||||
|
||||
**README 结构:**
|
||||
|
||||
```markdown
|
||||
# 项目名称
|
||||
|
||||
简要描述项目的功能。
|
||||
|
||||
## 安装
|
||||
|
||||
\`\`\`bash
|
||||
pip install myproject
|
||||
\`\`\`
|
||||
|
||||
## 快速开始
|
||||
|
||||
\`\`\`python
|
||||
from myproject import Client
|
||||
|
||||
client = Client(api_key="...")
|
||||
result = client.process(data)
|
||||
\`\`\`
|
||||
|
||||
## 配置
|
||||
|
||||
说明环境变量和配置选项。
|
||||
|
||||
## 开发
|
||||
|
||||
\`\`\`bash
|
||||
pip install -e ".[dev]"
|
||||
pytest
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
**CHANGELOG 格式(遵循 Keep a Changelog):**
|
||||
|
||||
```markdown
|
||||
# 更新日志
|
||||
|
||||
## [未发布]
|
||||
|
||||
### 新增
|
||||
- 新功能 X
|
||||
|
||||
### 变更
|
||||
- 修改了 Y 的行为
|
||||
|
||||
### 修复
|
||||
- 修复了 Z 中的 Bug
|
||||
```
|
||||
|
||||
## 最佳实践总结
|
||||
|
||||
1. **使用 ruff** —— 用于代码检查和格式化的单一工具
|
||||
2. **启用 strict mypy** —— 在运行时之前捕获类型错误
|
||||
3. **120 字符行长度** —— 现代可读性标准
|
||||
4. **描述性命名** —— 清晰性优于简洁性
|
||||
5. **绝对导入** —— 比相对导入更易于维护
|
||||
6. **Google 风格的文档字符串** —— 一致、可读的文档
|
||||
7. **记录公开 API** —— 每个公开函数都需要文档字符串
|
||||
8. **保持文档更新** —— 将文档视为代码
|
||||
9. **在 CI 中自动化** —— 每次提交都运行代码检查
|
||||
10. **目标 Python 3.10+** —— 对于新项目,建议使用 Python 3.12+ 以获得现代语言特性
|
||||
Reference in New Issue
Block a user