- 添加项目规则文档(开发规范、安全规则、配置管理) - 实现数据模块核心功能(API 客户端、限流器、存储管理、配置加载) - 添加 .gitignore 和 .kilocodeignore 配置 - 配置环境变量模板 - 编写 daily 模块单元测试
326 lines
8.4 KiB
Markdown
326 lines
8.4 KiB
Markdown
# 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/ # 测试数据
|
||
```
|
||
|
||
## 6 Git提交规范
|
||
|
||
### 6.1 提交信息格式
|
||
```
|
||
<type>(<scope>): <subject>
|
||
|
||
<body>
|
||
|
||
<footer>
|
||
```
|
||
|
||
### 6.2 类型标识
|
||
| 类型 | 说明 |
|
||
|------|------|
|
||
| feat | 新功能 |
|
||
| fix | Bug修复 |
|
||
| docs | 文档更新 |
|
||
| style | 代码格式调整 |
|
||
| refactor | 重构 |
|
||
| test | 测试相关 |
|
||
| chore | 构建/辅助工具 |
|
||
|
||
## 7 代码审查清单
|
||
|
||
- [ ] 代码符合PEP 8规范
|
||
- [ ] 关键配置未硬编码
|
||
- [ ] 函数/类添加了类型注解
|
||
- [ ] 复杂逻辑有注释说明
|
||
- [ ] 单元测试覆盖关键逻辑
|
||
- [ ] 无循环依赖
|
||
- [ ] 命名符合规范
|
||
- [ ] 日志不包含敏感信息
|