Files
2026-04-01 11:12:48 +08:00

136 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# **Python 编码与开发规范**
Python 是一门极其灵活的动态语言,但“灵活”在大型团队协作中往往意味着“灾难”。本规范以 **PEP 8** 为基石,全面拥抱 **现代 Python (3.9+)** 的类型注解系统,并强制依赖自动化工具链来消除代码风格争议。
## **命名约定与基础风格**
**核心理念:代码是写给人看的,顺便交给机器执行。**
* **变量与函数(变量/方法):** 强制使用 snake\_case下划线命名
\# 推荐
user\_account\_list \= \[\]
def fetch\_user\_data():
...
* **类名Classes** 强制使用 PascalCase大驼峰命名
class PaymentService:
...
class UserNotFoundError(Exception):
...
* **常量Constants** 强制使用 SCREAMING\_SNAKE\_CASE全大写加下划线定义在模块顶部。
* **布尔语义命名:** 布尔变量与布尔返回值应使用 `is_``has_``can_``allow_` 前缀,避免语义歧义。
* **集合语义命名:** 列表、集合、查询结果变量应使用复数命名(如 `users`, `orders`, `permission_codes`)。
* **私有与受保护属性:** \* 单下划线 \_private\_var表示内部使用软性约束仅作提示
* 双下划线 \_\_strict\_private触发名称改写Name Mangling除非极特殊情况如防止子类重写**日常业务开发中不推荐使用**,以免增加调试难度。
## **现代工程化工具链 (强制执行)**
**核心理念:能用工具自动修复的风格问题,绝不在 Code Review 中浪费时间口舌。**
项目中必须配置并使用以下工具链(推荐通过 pre-commit 钩子强制拦截不合规代码):
1. **项目与依赖管理uv (核心基石)**
* 摒弃传统的 pip、virtualenv 或臃肿的 Poetry全面拥抱由 Astral 团队用 Rust 编写的 uv。
* 它统一了虚拟环境管理、依赖解析和项目运行。使用 uv init 初始化项目uv add 添加依赖uv run 执行脚本,极大提升开发构建体验。
2. **综合 Linter 与格式化Ruff**
* 同样是 Astral 团队出品的极速工具,完美兼容并替代了 Flake8、isort 和 BlackRuff 目前已内置极速 formatter。团队统一在 pyproject.toml 中配置 Ruff 规则。
3. **静态类型检查Mypy**
* 开启严格模式。核心业务模块必须通过 Mypy 检查,不允许出现 Any 泛滥的情况。
## **类型注解 (Type Hinting) 规范**
**核心理念:动态一时爽,重构火葬场。所有业务接口、函数签名必须带有完整的类型注解。**
* **基础类型约束:** 充分利用 Python 3.9+ 的内置泛型(如 list, dict不再需要 from typing import List, Dict和 Python 3.10+ 的联合类型操作符 |。
\# 推荐写法 (Python 3.10+)
def process\_user\_data(user\_id: int | str, tags: list\[str\]) \-\> dict\[str, Any\]:
pass
* **可选类型:** 当参数或返回值可能为空时,必须使用 Optional\[T\] 或 T | None。
def find\_user(email: str) \-\> User | None:
pass
* **避免 Any 滥用:** 凡是写 Any 的地方,意味着放弃了类型检查。对于复杂的数据结构,应当优先定义 TypedDict 或数据模型类。
## **核心编码与设计范式**
### **1\. 数据模型设计 (Pydantic 与 Dataclass 的明确边界)**
**警惕过度设计:** 绝对不要为了用而用,将整个系统“全盘 Pydantic 化”。Pydantic 实例化时的类型强转和校验是有显著性能开销的,强行铺满内部逻辑会带来极大的工作量和性能负担。
* **必须使用 Pydantic 的场景(防腐层/系统边界):**
* 外部 API 的请求体与响应体验证(如 FastAPI 集成)。
* 外部配置文件的解析加载。
* 从不可靠来源(如第三方消息队列)消费的复杂 JSON 结构。
from pydantic import BaseModel, EmailStr
class UserCreateRequest(BaseModel):
name: str
email: EmailStr \# 外部输入,必须靠 Pydantic 严防死守
age: int | None \= None
* **必须使用 @dataclass 或 TypedDict 的场景(系统内部):**
* 内部 Service 函数之间的参数流转。
* 从数据库 ORM 查询出来、组装准备传给下一层的纯内部 DTO。
* 这些数据已经是“绝对可信”的,使用标准库的 @dataclass 可以实现近乎 O(1) 的轻量实例化,绝不增加无谓的校验负担。
### **2\. 函数参数设计 (关键字传参)**
* 当函数参数超过 3 个,或者包含容易混淆的布尔值时,**强制使用 \* 迫使调用方使用关键字传参**。
\# 规范示例调用此函数时age 和 is\_active 必须带上参数名
def create\_user(name: str, email: str, \*, age: int, is\_active: bool \= True) \-\> User:
pass
\# 调用端:
create\_user("John", "john@test.com", age=25, is\_active=False) \# 必须写明 age= 和 is\_active=
### **3\. 异常处理规约**
* **禁止吞噬异常:** 绝不允许出现 except Exception: pass 这种掩耳盗铃的代码。
* **自定义异常层次:** 模块应当抛出特定业务领域的异常(如继承自 ValueError 的 OrderNotFoundError而不是直接抛出裸露的 Exception。
* **边界层错误策略:** 在 API、CLI、任务入口等边界层应优先“抛异常并交由统一处理”避免在底层函数中拼接错误响应字符串。
### **4\. 资源释放与安全**
* **强制使用上下文管理器:** 文件读写、网络会话(如 requests.Session、数据库连接必须使用 with 语句包裹,确保资源(哪怕在异常抛出时)能被正确关闭。
## **性能优化与防坑指南**
Python 性能上限不高,但不良写法会导致下限极低:
* **查找操作慎用 List拥抱 Set/Dict**
* if item in my\_list: 的时间复杂度是 O(n)。对于包含上百个元素的成员判断,**必须**将集合初始化为 Set 或 Dict以达到 O(1) 的查找性能。
* **大数据流拥抱生成器 (Generators)**
* 当处理百万级行数的 CSV 或大量数据库记录时,严禁将数据一次性加载到内存的 List 中。**必须使用 yield**。
def process\_large\_file(filename: str):
with open(filename, 'r') as file:
for line in file:
yield process\_line(line) \# 内存中始终只有一行数据
* **海量实例的内存优化:**
* 当需要实例化上百万个轻量级对象时,必须在类中声明 \_\_slots\_\_ \= \['attr1', 'attr2'\],这能节约约 40% 的内存消耗(阻止 Python 为每个实例创建 \_\_dict\_\_
## **单元测试规范**
* **测试框架选型:** 统一使用 pytest废弃 Python 自带的厚重 unittest 类式写法。并通过 uv run pytest 执行。
* **测试用例结构:** 遵循 Arrange \- Act \- Assert (准备-执行-断言) 三段式结构。
* **Mock 的边界:** 严禁在单元测试中发起真实的 HTTP 网络请求或连接真实的 MySQL 数据库。必须使用 unittest.mock.patch 或 pytest-mock 对外部 IO 依赖进行拦截和模拟。
def test\_get\_user\_info(mocker):
\# Arrange: 拦截外部数据库调用
mocker.patch('myproject.database.fetch', return\_value={"id": 1, "name": "Test"})
\# Act
user \= get\_user\_info(1)
\# Assert
assert user.name \== "Test"
## 🤖 [附加] AI 助手执行协议 (AI Output Schema)
**绝对红线**:生成的 Python 代码必须 100% 包含 Type Hints类型注解禁止输出废话解析直接输出带规范中文注释的可用代码块。