Files
ProStock/.kilocode/rules/python-development-guidelines.md

357 lines
9.5 KiB
Markdown
Raw Normal View History

# Python 开发规范
## 1 代码风格规范
### 1.1 缩进与空格
- 使用 **4个空格** 进行缩进禁止使用Tab
- 每行代码最大长度限制为 **120字符**
- 二元运算符前后使用空格(链式赋值除外)
- 函数参数周围空格一致
```python
# 正确示例
def calculate_total_price(price: float, tax_rate: float) -> float:
total = price * (1 + tax_rate)
return round(total, 2)
# 错误示例
def calculate_total_price(price:float,tax_rate:float)->float:
total=price*(1+tax_rate)
return round(total,2)
```
### 1.2 导入规范
- 导入位于文件顶部,位于模块注释和文档字符串之后
- 标准库导入放在最前面,其次是第三方库,最后是本地应用模块
- 使用绝对导入,禁止使用通配符导入(`from module import *`
- 每组导入之间保留一个空行
```python
# 标准库
import os
import sys
from datetime import datetime
# 第三方库
import numpy as np
import pandas as pd
from pydantic import BaseModel
# 本地模块
from src.config import settings
from src.utils.logger import get_logger
```
### 1.3 命名规范
| 类型 | 规范 | 示例 |
|------|------|------|
| 模块 | 全小写,下划线分隔 | `data_processor.py` |
| 包 | 全小写,禁止下划线 | `src/utils` |
| 类 | PascalCase首字母大写 | `UserAccount`, `DataValidator` |
| 函数 | snake_case全小写 | `get_user_data()`, `calculate_total()` |
| 变量 | snake_case全小写 | `user_name`, `total_count` |
| 常量 | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT`, `DEFAULT_TIMEOUT` |
| 私有方法/变量 | 单下划线前缀 | `_internal_method()`, `_private_var` |
| 类型变量 | PascalCase | `UserType`, `T = TypeVar('T')` |
### 1.4 注释规范
- 使用英文注释,禁止使用中文注释
- 复杂逻辑必须添加注释说明意图
- 注释与代码同步更新,禁止过时注释
```python
# 单行注释与代码同行时注释前保留2个空格
def process_data(data: list) -> dict: # Process input data and return statistics
pass
# 多行文档字符串Google风格
def calculate_metrics(values: list[float]) -> dict[str, float]:
"""Calculate statistical metrics for a list of values.
Args:
values: List of numeric values to analyze
Returns:
Dictionary containing mean, median, and standard deviation
Raises:
ValueError: If input list is empty
"""
pass
```
## 2 架构设计规范
### 2.1 模块结构
```
src/
├── core/ # 核心业务逻辑
├── modules/ # 功能模块
├── utils/ # 工具函数
├── config/ # 配置管理
├── services/ # 服务层
├── models/ # 数据模型
├── repositories/ # 数据访问层
└── schemas/ # Pydantic模型
```
### 2.2 依赖原则
- **依赖倒置**:高层模块不依赖低层模块,两者都依赖抽象
- **禁止循环依赖**:模块间引用必须形成有向无环图
- **单一职责**:每个类/模块只负责一项职责
```python
# 错误示例:高内聚低耦合违反
class UserService:
def __init__(self, db_connection, email_sender, cache_manager):
pass
# 正确示例:通过抽象接口解耦
class UserService:
def __init__(self, user_repository: IUserRepository):
self.repository = user_repository
```
### 2.3 函数设计
- **单一职责**:每个函数只做一件事
- **参数控制**函数参数不超过5个超过则使用对象封装
- **返回值明确**:返回类型必须注解
```python
# 错误示例:函数职责过多
def process_user_registration(name, email, password, send_email, create_session):
if send_email:
send_verification_email(email)
if create_session:
create_user_session(email)
return save_user(name, email, password)
# 正确示例:单一职责拆分
class UserRegistrationService:
def register(self, user_data: UserCreateDto) -> User:
user = self._validate_and_create_user(user_data)
self._send_verification_email(user)
self._create_session(user)
return user
def _validate_and_create_user(self, data: UserCreateDto) -> User:
pass
def _send_verification_email(self, user: User) -> None:
pass
```
## 3 配置管理规范
### 3.1 禁止硬编码
**所有关键配置必须外置,禁止在代码中硬编码**
| 类型 | 必须外置的配置 |
|------|----------------|
| 数据库连接 | HOST, PORT, USER, PASSWORD, DATABASE |
| API密钥 | SECRET_KEY, API_KEY |
| 外部服务 | ENDPOINT, TIMEOUT, RETRY_COUNT |
| 业务参数 | MAX_RETRIES, CACHE_TTL, RATE_LIMIT |
### 3.2 配置目录结构
```
config/
├── .env.example # 环境变量模板(不包含敏感信息)
├── .env.local # 本地环境配置(被.gitignore忽略
├── config.yaml # 通用配置
├── config.development.yaml # 开发环境配置
├── config.production.yaml # 生产环境配置
└── config.test.yaml # 测试环境配置
```
### 3.3 配置加载示例
```python
# src/config/settings.py
from pydantic_settings import BaseSettings
from functools import lru_cache
class Settings(BaseSettings):
"""应用配置类,从环境变量加载"""
# 数据库配置
database_host: str = "localhost"
database_port: int = 5432
database_name: str = "prostock"
database_user: str
database_password: str
# API配置
api_key: str
secret_key: str
jwt_algorithm: str = "HS256"
access_token_expire_minutes: int = 30
# Redis配置
redis_host: str = "localhost"
redis_port: int = 6379
class Config:
env_file = ".env.local"
env_file_encoding = "utf-8"
@lru_cache()
def get_settings() -> Settings:
"""获取配置单例"""
return Settings()
```
### 3.4 .env.example 模板
```bash
# ===========================================
# ProStock 环境变量配置模板
# 复制此文件为 .env.local 并填入实际值
# ===========================================
# 数据库配置
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=prostock
DATABASE_USER=your_username
DATABASE_PASSWORD=your_password
# API密钥配置
API_KEY=your_api_key
SECRET_KEY=your_secret_key_here
# Redis配置可选
REDIS_HOST=localhost
REDIS_PORT=6379
```
## 4 错误处理规范
### 4.1 异常分类
```python
# src/core/exceptions.py
class BaseCustomException(Exception):
"""基础异常类"""
status_code: int = 500
detail: str = "An unexpected error occurred"
def __init__(self, detail: str = None):
self.detail = detail or self.detail
super().__init__(self.detail)
class ValidationError(BaseCustomException):
"""数据验证异常"""
status_code = 422
detail = "Validation error"
class AuthenticationError(BaseCustomException):
"""认证异常"""
status_code = 401
detail = "Authentication required"
class AuthorizationError(BaseCustomException):
"""授权异常"""
status_code = 403
detail = "Permission denied"
class NotFoundError(BaseCustomException):
"""资源不存在"""
status_code = 404
detail = "Resource not found"
```
### 4.2 错误处理原则
- 向上层传递有意义的信息
- 记录详细日志(不含敏感信息)
- 区分可恢复和不可恢复错误
## 5 测试规范
### 5.1 测试要求
- 所有核心功能必须有单元测试
- 关键业务逻辑测试覆盖率不低于80%
- 使用 `pytest` 作为测试框架
- 使用 `pytest-cov` 生成覆盖率报告
### 5.2 测试文件结构
```
tests/
├── conftest.py # 共享fixtures
├── unit/ # 单元测试
│ ├── test_models.py
│ ├── test_services.py
│ └── test_utils.py
├── integration/ # 集成测试
│ └── test_api.py
└── fixtures/ # 测试数据
```
### 5.3 Mock 使用规范
- **默认不使用 Mock**:单元测试应直接调用真实 API 或服务
- **仅在必要时使用 Mock**
- 测试错误处理场景(如网络超时、服务不可用)
- 测试空结果或边界情况
- 隔离外部依赖的不确定性
- **禁止全面 Mock**:不应为避免配置或环境问题而使用 Mock
- **真实环境验证**:确保至少有一个测试套件直接调用真实 API
```python
# 正确示例:直接调用真实 API
class TestUserService:
def test_get_user(self):
result = get_user('user_id')
assert result.name == "John"
def test_empty_result_with_mock(self): # 特殊场景使用 mock
with patch('module.api_call', return_value=pd.DataFrame()):
result = get_user('invalid_id')
assert result.empty
# 错误示例:过度使用 mock
class TestUserService:
def test_get_user(self):
mock_data = {"name": "John"}
with patch('module.api_call', return_value=mock_data):
result = get_user('user_id')
assert result == mock_data
```
## 6 Git提交规范
### 6.1 提交信息格式
```
<type>(<scope>): <subject>
<body>
<footer>
```
### 6.2 类型标识
| 类型 | 说明 |
|------|------|
| feat | 新功能 |
| fix | Bug修复 |
| docs | 文档更新 |
| style | 代码格式调整 |
| refactor | 重构 |
| test | 测试相关 |
| chore | 构建/辅助工具 |
## 7 代码审查清单
- [ ] 代码符合PEP 8规范
- [ ] 关键配置未硬编码
- [ ] 函数/类添加了类型注解
- [ ] 复杂逻辑有注释说明
- [ ] 单元测试覆盖关键逻辑
- [ ] 无循环依赖
- [ ] 命名符合规范
- [ ] 日志不包含敏感信息
- [ ] 测试未过度使用 Mock