writing-python

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Python Development (3.14+)

Python 3.14+ 开发指南

Core Philosophy

核心原则

  1. Stdlib and Mature Libraries First
    • Always prefer Python stdlib solutions
    • External deps only when stdlib insufficient
    • Prefer dataclasses over attrs, pathlib over os.path
  2. Type Hints Everywhere (No Any)
    • Python 3.14 has lazy annotations by default
    • Use Protocol for structural typing (duck typing)
    • Avoid Any—use concrete types or generics
  3. Protocol Over ABC
    • Protocol for implicit interface satisfaction
    • ABC only when runtime isinstance() needed
    • Protocols are more flexible and Pythonic
  4. Flat Control Flow
    • Guard clauses with early returns
    • Pattern matching to flatten conditionals
    • Maximum 2 levels of nesting
  5. Explicit Error Handling
    • Custom exception hierarchy for domain errors
    • Raise early, handle at boundaries
    • except ValueError | TypeError: (no parens)
  1. 优先使用标准库与成熟库
    • 始终优先选择Python标准库方案
    • 仅当标准库无法满足需求时才使用外部依赖
    • 优先使用dataclasses而非attrs,优先使用pathlib而非os.path
  2. 全面使用类型提示(禁用Any)
    • Python 3.14默认支持延迟注解
    • 使用Protocol实现结构化类型(鸭子类型)
    • 避免使用Any类型,改用具体类型或泛型
  3. 优先使用Protocol而非ABC
    • 使用Protocol实现隐式接口适配
    • 仅当需要运行时isinstance()检查时才使用ABC
    • Protocol更灵活且符合Python风格
  4. 扁平化控制流
    • 使用卫语句提前返回
    • 使用模式匹配简化条件判断
    • 最多允许2层嵌套
  5. 显式错误处理
    • 为领域错误定义自定义异常层级
    • 尽早抛出异常,在边界处处理
    • 支持
      except ValueError | TypeError:
      写法(无需括号)

Quick Patterns

快速实践模式

Protocol-Based Dependency Injection

基于Protocol的依赖注入

python
from typing import Protocol
python
from typing import Protocol

Protocol at consumer (like Go interfaces)

Protocol at consumer (like Go interfaces)

class UserStore(Protocol): def get(self, id: str) -> User | None: ... def save(self, user: User) -> None: ...
class UserService: def init(self, store: UserStore): self.store = store # accepts any matching impl
undefined
class UserStore(Protocol): def get(self, id: str) -> User | None: ... def save(self, user: User) -> None: ...
class UserService: def init(self, store: UserStore): self.store = store # accepts any matching impl
undefined

Flat Control Flow (No Nesting)

扁平化控制流(无嵌套)

python
undefined
python
undefined

GOOD: guard clauses, early returns

推荐写法:卫语句+提前返回

def process(user: User | None) -> Result: if user is None: raise ValueError("user required") if not user.email: raise ValueError("email required") if not is_valid_email(user.email): raise ValueError("invalid email") return do_work(user) # happy path at end
def process(user: User | None) -> Result: if user is None: raise ValueError("user required") if not user.email: raise ValueError("email required") if not is_valid_email(user.email): raise ValueError("invalid email") return do_work(user) # 主逻辑放在最后

BAD: nested conditions

不推荐写法:嵌套条件

def process(user: User | None) -> Result: if user is not None: if user.email: if is_valid_email(user.email): return do_work(user) raise ValueError("invalid")
undefined
def process(user: User | None) -> Result: if user is not None: if user.email: if is_valid_email(user.email): return do_work(user) raise ValueError("invalid")
undefined

Pattern Matching

模式匹配

python
undefined
python
undefined

Flatten complex conditionals with match

使用match简化复杂条件判断

match event: case {"type": "click", "x": x, "y": y}: handle_click(x, y) case {"type": "key", "code": code}: handle_key(code) case _: raise ValueError(f"Unknown event: {event}")
undefined
match event: case {"type": "click", "x": x, "y": y}: handle_click(x, y) case {"type": "key", "code": code}: handle_key(code) case _: raise ValueError(f"Unknown event: {event}")
undefined

Type Hints (No Any)

类型提示(禁用Any)

python
undefined
python
undefined

GOOD: concrete types

推荐写法:具体类型

def process_users(users: list[User], limit: int | None = None) -> list[Result]: ...
def process_users(users: list[User], limit: int | None = None) -> list[Result]: ...

GOOD: generics when needed

推荐写法:按需使用泛型

from typing import TypeVar T = TypeVar("T") def first(items: list[T]) -> T | None: return items[0] if items else None
from typing import TypeVar T = TypeVar("T") def first(items: list[T]) -> T | None: return items[0] if items else None

BAD: unnecessary Any

不推荐写法:不必要的Any类型

def process(data: Any) -> Any: # Don't do this ...
undefined
def process(data: Any) -> Any: # 请勿这样写 ...
undefined

Error Handling

错误处理

python
undefined
python
undefined

except without parens (3.14)

3.14特性:无需括号的except语句

except ValueError | TypeError: handle_error()
except ValueError | TypeError: handle_error()

Custom exceptions

自定义异常

class NotFoundError(AppError): def init(self, resource: str, id: str): self.resource = resource self.id = id super().init(f"{resource} not found: {id}")
undefined
class NotFoundError(AppError): def init(self, resource: str, id: str): self.resource = resource self.id = id super().init(f"{resource} not found: {id}")
undefined

Python 3.14 Features

Python 3.14 新特性

  • Deferred annotations: No
    from __future__ import annotations
  • Template strings (t""):
    t"Hello {name}"
    returns Template
  • except without parens:
    except ValueError | TypeError:
  • concurrent.interpreters: True parallelism
  • compression.zstd: Zstandard in stdlib
  • Free-threaded build: No GIL (opt-in)
  • 延迟注解:无需导入
    from __future__ import annotations
  • 模板字符串(t"")
    t"Hello {name}"
    会返回Template对象
  • 无括号except语句:支持
    except ValueError | TypeError:
    写法
  • concurrent.interpreters:实现真正的并行执行
  • compression.zstd:标准库内置Zstandard压缩支持
  • 无全局解释器锁(GIL)构建:可选启用无GIL模式

References

参考资料

  • PATTERNS.md - Code patterns and style
  • CLI.md - CLI application patterns
  • TESTING.md - Testing with pytest
  • PATTERNS.md - 代码模式与风格指南
  • CLI.md - CLI应用开发模式
  • TESTING.md - 使用pytest进行测试

Tooling

工具链

bash
uv sync                    # Install deps
ruff check --fix .         # Lint and autofix
ruff format .              # Format
pytest -v                  # Test
mypy .                     # Type check
bash
uv sync                    # 安装依赖
ruff check --fix .         # 代码检查并自动修复
ruff format .              # 代码格式化
pytest -v                  # 运行测试
mypy .                     # 类型检查