mcpField
P
python-best-practices

python-best-practices

github.com/alleneubank开发502.2k 次安装18 周前更新
代码仓库

关于 python-best-practices

面向编码 Agent 的 Python 技能,涵盖类型优先设计、错误处理、结构化日志和语言习惯。还介绍可选的类型检查工具及其适用场景。

主要功能

  1. 01不可变 dataclass
  2. 02类型化联合与 NewType
  3. 03使用 Protocol 进行结构化类型检查
  4. 04异常链
  5. 05结构化日志

适用场景

  1. 01建模不可变领域数据
  2. 02避免无效类型值
  3. 03抛出错误时保留回溯信息
  4. 04选择 Python 类型检查器

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alleneubank/claude-code --skill python-best-practices

安装后在 Claude Code 中输入/python-best-practices确认已加载。

详细介绍

Python 最佳实践

遵循 CLAUDE.md 中以类型优先、函数式和错误处理为核心的模式。本指南仅涵盖语言特定的惯用写法。

让非法状态无法表示

使用 Python 的类型系统,在类型检查时防止无效状态。

使用冻结的数据类表示不可变领域模型:

from dataclasses import dataclass
from datetime import datetime

@dataclass(frozen=True)
class User:
    id: str
    email: str
    name: str
    created_at: datetime

# Frozen dataclasses are immutable — no accidental mutation

使用 Literal 表示判别联合:

from dataclasses import dataclass
from typing import Literal

@dataclass
class Success:
    status: Literal["success"] = "success"
    data: str

@dataclass
class Failure:
    status: Literal["error"] = "error"
    error: Exception

RequestState = Success | Failure

def handle_state(state: RequestState) -> None:
    match state:
        case Success(data=data):
            render(data)
        case Failure(error=err):
            show_error(err)

使用 NewType 表示领域原始类型:

from typing import NewType

UserId = NewType("UserId", str)
OrderId = NewType("OrderId", str)

def get_user(user_id: UserId) -> User:
    # Type checker prevents passing OrderId here
    ...

使用 Protocol 进行结构化类型检查:

from typing import Protocol

class Readable(Protocol):
    def read(self, n: int = -1) -> bytes: ...

def process_input(source: Readable) -> bytes:
    # Accepts any object with a read() method — no inheritance required
    return source.read()

Python 特定的错误处理

使用 from err 链接异常,以保留原始回溯:

try:
    data = json.loads(raw)
except json.JSONDecodeError as err:
    raise ValueError(f"invalid JSON payload: {err}") from err

结构化日志记录

使用模块级 logger 和 %s 格式化(延迟字符串插值):

import logging

logger = logging.getLogger("myapp.widgets")

def create_widget(name: str) -> Widget:
    logger.debug("creating widget: %s", name)
    widget = Widget(name=name)
    logger.debug("created widget id=%s", widget.id)
    return widget

可选:ty

如需快速类型检查,可考虑使用 Astral(ruff 和 uv 的开发者)提供的 ty。它以 Rust 编写,速度显著快于 mypy 或 pyright。

uvx ty check          # run directly, no install needed
uvx ty check src/     # check specific path
# pyproject.toml
[tool.ty]
python-version = "3.12"

选择时机:

  • ty — 速度最快,适合 CI 和大型代码库(目前仍处于早期阶段,快速演进中)
  • pyright — 类型推断最全面,并集成 VS Code
  • mypy — 成熟,插件生态丰富

评论

支持 Markdown