## Python 规范

### 依赖管理

- **使用 uv 管理依赖**
  ```bash
  uv init --python 3.12 .
  uv add <package_name>
  ...
  uv sync
  uv lock # 锁定确切版本
  ```
- **明确区分生产依赖和开发依赖**
  - 生产依赖：`uv add <package_name>`
  - 开发依赖（测试、构建、静态检查等）：`uv add --dev <package_name>`
- **明确版本约束**
  - 在 `pyproject.toml` 中使用语义化版本约束，避免因依赖库大版本更新（如
    Pydantic V1 -> V2）导致的不兼容问题。
  - 示例：`pydantic>=2.0,<3.0`
- **补充类型存根**
  - 对于不自带类型定义的第三方库，必须添加对应的 `types-*` 包以支持静态类型检查
    。
  - 示例：`uv add types-requests types-pytz`

### 代码规则

- **显式声明类型**
  - 方法参数、属性、返回值等必须显式声明类型。
  - 禁止使用 `Dict` 传递非结构化的参数、返回值或数据对象，应使用 `dataclass` 或
    `Pydantic` 模型。

```python
from pydantic import BaseModel, field_validator

class Config(BaseModel):
    min_poll_interval: int = 5
    max_poll_interval: int = 1800

    @field_validator('max_poll_interval')
    @classmethod
    def validate_max_greater_than_min(cls, v, info):
        if 'min_poll_interval' in info.data and v <= info.data['min_poll_interval']:
            raise ValueError('max_poll_interval must be greater than min_poll_interval')
        return v
```

- **用绝对导入**
  - 使用绝对导入，而不是相对导入。
  - 绝对导入的优点是：更清晰，更容易理解。

- **运行时数据验证**
  - 充分利用 Pydantic 的验证器（`@field_validator`）对配置、API 输入等进行严格的
    运行时检查，提前防止数据错误。
- **构造函数初始化**
  - 实例必须的初始化工作应当在 `__init__` 构造函数里完成，而不是让调用者额外调用
    “init” 方法。
- **遵循 PEP 8**
  - 使用 Black + Ruff/isort 自动格式化和检查。
  - 最大行宽不超过 88（Black 默认）或团队约定值。
- **命名规范**
  - 模块、变量、函数：`snake_case`
  - 类名、异常名：`PascalCase`
  - 常量：`UPPER_SNAKE_CASE`
  - 内部方法/函数 名字需要以 _ 开头
- **文档与注释**
  - 每个模块、类、函数都要有 docstring，遵循 Google 样式。
  - 在复杂逻辑处添加必要注释，解释“为什么”这么做，而不是“做了什么”。

### 接口与抽象

- **合理使用 `typing.Protocol`**
  - **价值**：在策略和插件化场景下，用协议定义契约比显式继承更灵活，既保持了低耦
    合，又兼顾了 IDE 智能补全和 Mypy 校验。
  - **建议**：对外暴露的接口优先使用 `Protocol`，内部默认实现再继承或注册。

### 配置管理

- **引入 `pydantic-settings` 统一配置**
  - **价值**：把 `.env`、环境变量、CLI 参数统一为 Pydantic 模型，避免项目里到处
    零散地调用 `os.getenv`，提高了配置的可追溯性和类型安全。
  - **建议**：新建一个 `Settings` 类集中管理，配合 `uv add pydantic-settings` 并
    在 `uv.sync` 后自动生成对应代码片段。

### 日志管理

- **结构化日志 (structlog + JSON sink)**
  - **价值**：标准化日志字段（`timestamp`、`level`、`event`、`trace_id`…），与
    ELK/Loki/ClickHouse 等分析平台无缝集成，提升故障定位与监控能力。
  - **建议**：从项目骨架开始引入，定义公共 `Logger` 配置，并在 CI 或部署文档中说
    明如何在生产环境启动 JSON 输出。

### 安全规范

- **输入验证与净化**
  - 所有外部输入（API 请求、配置文件、用户上传内容等）都必须通过 Pydantic 模型进
    行严格的验证和类型转换。
- **敏感数据处理**
  - 禁止在日志中明文记录密码、API Key 等敏感信息。
  - 使用 `pydantic-settings` 等工具从环境变量或安全的 Secret 管理服务中加载敏感
    配置。
- **依赖库安全性检查**
  - 定期使用 `uv audit` 或 `pip-audit` 扫描项目依赖，及时发现并修复已知的安全漏
    洞。
  - 在 CI 流程中集成依赖扫描步骤。

### 测试最佳实践

- **测试行为而非实现**
  - 单元测试应验证公共接口的业务逻辑和行为，而不是其内部实现细节。
- **隔离测试单元**
  - 必须 Mock 所有外部依赖（如 API 调用、数据库、文件系统），确保测试的独立性和
    稳定性。
- **集成测试策略**
  - 编写集成测试来验证关键模块间的交互，例如服务与数据库的连接。
  - 使用测试容器（Testcontainers）或 Docker Compose 为集成测试提供隔离的、真实的
    依赖服务。
- **性能测试**
  - 对性能敏感的关键路径，使用 `pytest-benchmark` 等工具编写基准测试，防止性能回
    退。
- **测试数据管理**
  - 使用 `Faker` 等库生成隔离且可复现的测试数据。
  - 严禁在测试中使用生产环境数据。
- **处理无头环境中的 GUI 依赖**

  - 在无头（Headless）CI/CD 环境中，若项目依赖 GUI 库（如 `pyautogui`），会导致
    `DISPLAY` 环境变量缺失错误。
  - **解决方案**：在 `tests/conftest.py` 中提前 Mock 相关的 GUI 模块。

    ```python
    # tests/conftest.py
    import sys
    from unittest.mock import MagicMock

    # 在导入测试用例前Mock GUI相关模块
    sys.modules['pyautogui'] = MagicMock()
    sys.modules['pygetwindow'] = MagicMock()
    ```

- **编写健壮的测试**
  - 测试用例应具备健壮性，不应依赖具体的、可能变化的实现细节（如时区缩写 "CST"
    vs "LMT"）。应测试其核心逻辑。
  - 使用参数化测试（`@pytest.mark.parametrize`）覆盖边界条件和异常情况。

### 异常处理最佳实践

1. **捕获具体异常**  
   避免使用 `except Exception:` 或裸 `except:`，应捕获特定异常。

2. **记录日志而非打印**  
   在 `except` 块中使用 `logging` 模块记录异常信息（包括堆栈跟踪）。

3. **定义自定义异常类**  
   针对业务领域定义专用异常类，使错误类型更加语义化。

4. **利用 `else` 与 `finally`**

   - `else`：用于“正常流程”代码。
   - `finally`：用于资源清理，确保总能执行。

5. **让意外异常继续冒泡**  
   只处理预期内的异常，不隐藏未知错误。

6. **结合上下文管理器**  
   优先使用 `with` 语句管理资源，自动处理异常和清理。

### 性能优化指南

- **内存使用优化**
  - 优先使用生成器（`yield`）处理大型数据集，避免一次性加载到内存。
  - 对固定且属性较多的对象使用 `__slots__` 来减少内存占用。
- **并发/异步编程**
  - 对 I/O 密集型任务，优先使用 `asyncio` 和 `async/await` 提高并发能力。
  - 避免在异步代码中调用阻塞的 I/O 操作。
- **大数据处理**
  - 在处理大型表格数据时，考虑使用 `Polars` 等高性能库。
  - 数据处理应以流式（Streaming）或分块（Chunking）方式进行。

### 静态类型检查

- 使用 **Mypy**（或 **Pyright**）在 CI 中强制执行类型检查。
  ```bash
  mypy .
  ```
- 推荐启用 `--strict` 模式，或根据团队情况定制 `pyproject.toml` 中的
  `[tool.mypy]` 配置。

- **全面开启 Ruff**
  - **价值**：在 PEP 8 之外，再覆盖现代化升级提示（UP\*）、常见 Bug（B/BLE）、安
    全隐患（S）等规则，一次性收割多类质量红利。
  - **建议**：在 `pyproject.toml` 中启用最全的 `select` 集合，CI 里把 Ruff 报错
    作为门禁。

### 项目文档与知识沉淀

- **记录已知“坑点”**

  - 在项目 `CLAUDE.md` 或 `README.md` 中，必须建立一个专门区域，记录开发过程中遇
    到的特有问题、环境陷阱和解决方案。
  - **示例记录**：
    > #### 项目特有的异常行为或警告
    >
    > 1. **GUI 依赖问题**: 在无头环境测试需要 Mock `pyautogui`。
    > 2. **时区格式化**: `pytz` 库对北京时区的缩写可能返回 `LMT` 而非 `CST`，测
    >    试时需灵活判断。

- **提供环境配置文档**
  - 为新成员准备清晰的环境配置指南，包括必要的环境变量和工具链。

### 环境与工作流

- 在项目根目录提供 `Makefile` 或 `pyproject.toml [project.scripts]` 封装常用命令
  。

```toml
# pyproject.toml
[project.scripts]
lint = "ruff check . --fix"
format = "black ."
test = "pytest --cov=src"
check = "mypy ."
```

- **使用 pre-commit Hooks**
  - 强烈建议配置 pre-commit，在代码提交前自动执行格式化和静态检查，保证代码质量

### 团队协作与发布流程

- **代码审查清单**
  - 在项目中创建 `PULL_REQUEST_TEMPLATE.md`，提供一个清单，确保审查点（如测试覆
    盖、文档更新、遵循规范）不被遗漏。
- **版本管理策略**
  - 遵循语义化版本（SemVer）规范（主版本.次版本.修订号）。
  - 使用 Git 标签（`git tag`）标记每个正式发布版本。
- **发布流程**
  - 推荐使用 CI/CD 流水线自动化测试、构建和发布流程。

### 语言限制

- **禁止在运行时变更对象布局**

  - 所有类必须声明 `__slots__` 或使用冻结（immutable）数据类，从根本上禁用动态增
    删属性。

  ```python
  from dataclasses import dataclass

  @dataclass(frozen=True, slots=True)
  class Point:
      x: float
      y: float

  # 使用 frozen=True 和 slots=True 同时获得不可变性和性能优化
  # 任何修改属性或添加新属性的操作都会抛出异常
  ```

- **「禁止 Any」与「全员 frozen + slots」**

  - **价值**：极大提升类型检查严格度和运行时内存／访问性能，并防止动态增删属性引
    发的隐蔽 Bug。
  - **建议**：主业务代码强制执行，测试代码，实验性或 PoC 模块可在 `mypy.ini` 中
    针对性豁免；同时在代码审查中重点关注。
    ```toml
    [mypy]
    disallow_untyped_defs = True # 所有函数/方法必须有类型注释
    disallow_any_unimported = True # 禁止隐式 Any（未导入类型）
    disallow_any_explicit = True # 禁止显式 Any
    warn_unused_ignores = True
    no_implicit_optional = True
    [mypy-poc.*] # 实验性或 PoC 模块
    disallow_untyped_defs = False
    disallow_any_explicit = False
    [mypy-tests.*]
    disallow_untyped_defs = False
    disallow_any_explicit = False
    ```

- **谨慎使用运算符重载**

  - **原则**：仅在能显著提高代码可读性和表达力时才使用运算符重载，避免滥用。
  - **适用场景**：主要用于数学计算（如向量、矩阵）、数据分析或构建领域特定语言（
    DSL）等，此时重载能让代码更自然、更符合领域习惯。
  - **禁止场景**：避免在通用业务对象上重载运算符，这会降低代码的清晰度和可维护性
    。

  ```python
  # ✅ 推荐：在数学/几何领域，重载使代码更直观
  class Vector:
      def __init__(self, x, y):
          self.x, self.y = x, y
      def __add__(self, other):
          return Vector(self.x + other.x, self.y + other.y)

  # ❌ 不推荐：在业务对象上重载，含义模糊
  class ShoppingCart:
      def __add__(self, item): ... # 含义不清晰，应使用 .add_item(item)
  ```

### 信号处理与优雅关闭

- 使用 `signal.signal()` 注册 `SIGTERM`/`SIGINT` 处理函数，收到信号后停止接收新任务，优雅退出。
- 在 `try...finally` 中确保调用子进程或线程的 `join()`/`close()`，避免僵尸进程或资源泄漏。

### 测试与调试

- `pytest` 命令加上 `-s --durations=0 --log-cli-level=INFO`，保证子进程日志和耗时信息完整输出。
