跳转到内容

Python模式

来源: everything-claude-code 技能库

python-patterns 涵盖 Pythonic 惯用语、PEP 8 标准、类型提示和构建健壮、高效、可维护应用的最佳实践。

Python 优先考虑可读性。代码应该清晰易懂:

# 好:清晰易读
def get_active_users(users: list[User]) -> list[User]:
"""从提供的列表中返回活跃用户。"""
return [user for user in users if user.is_active]
# 不好:聪明但费解
def get_active_users(u):
return [x for x in u if x.a]

避免魔法;要清楚代码做什么:

# 好:显式配置
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# 不好:隐藏的副作用
import some_module
some_module.setup() # 这是做什么的?

3. EAFP - 争取宽恕比请求许可更好

Section titled “3. EAFP - 争取宽恕比请求许可更好”

Python 更喜欢异常处理而非条件检查:

# 好:EAFP 风格
def get_value(dictionary: dict, key: str) -> Any:
try:
return dictionary[key]
except KeyError:
return None
# 不好:LBYL 风格
def get_value(dictionary: dict, key: str) -> Any:
if key in dictionary:
return dictionary[key]
return None

优先使用组合而非继承:

# 好:组合
class Logger:
def log(self, message):
print(message)
class UserService:
def __init__(self, logger: Logger):
self.logger = logger
def create_user(self, name):
self.logger.log(f"Creating user: {name}")
# 不好:过度继承
class UserServiceWithLogging(UserService):
# 继承所有方法,可能不需要
pass

类型提示让代码更清晰,IDE 支持更好:

# 变量类型
name: str = "张三"
age: int = 25
prices: list[float] = [1.5, 2.0, 3.5]
user_dict: dict[str, User] = {}
# 函数类型提示
def greet(name: str) -> str:
return f"Hello, {name}!"
def process_items(items: list[int]) -> dict[str, int]:
return {
"sum": sum(items),
"count": len(items),
"avg": sum(items) / len(items)
}
from typing import Optional, Union, Callable, TypeVar, Generic
# Optional - 可能为 None
def find_user(user_id: int) -> Optional[User]:
# 可能返回 User 或 None
pass
# Union - 多种类型
def process_input(value: Union[str, int]) -> str:
return str(value)
# Callable - 可调用对象
def apply_function(func: Callable[[int], int], value: int) -> int:
return func(value)
# TypeVar - 泛型
T = TypeVar('T')
def first_element(items: list[T]) -> Optional[T]:
return items[0] if items else None
from dataclasses import dataclass
from pydantic import BaseModel
# dataclass - 简单数据容器
@dataclass
class User:
name: str
email: str
age: int = 0 # 默认值
# Pydantic - 数据验证
class UserModel(BaseModel):
name: str
email: str
age: int = 0
@validator('email')
def email_must_be_valid(cls, v):
if '@' not in v:
raise ValueError('Invalid email')
return v
# 类方式
class FileManager:
def __init__(self, filename: str):
self.filename = filename
def __enter__(self):
self.file = open(self.filename, 'r')
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
# 函数方式(推荐)
from contextlib import contextmanager
@contextmanager
def managed_resource():
resource = acquire_resource()
try:
yield resource
finally:
release_resource(resource)
# 使用
with managed_resource() as resource:
# 使用资源
pass
class Counter:
def __init__(self, limit: int):
self.limit = limit
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= self.limit:
raise StopIteration
self.current += 1
return self.current
# 使用生成器
def count_to(limit: int):
current = 1
while current <= limit:
yield current
current += 1
config.py
# 方式 1:模块级单例
class _Config:
value = None
config = _Config()
# 方式 2:装饰器
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class Database:
pass
class Subject:
def __init__(self):
self._observers = []
def attach(self, observer):
self._observers.append(observer)
def detach(self, observer):
self._observers.remove(observer)
def notify(self, *args, **kwargs):
for observer in self._observers:
observer.update(*args, **kwargs)
class Observer:
def update(self, message):
print(f"Received: {message}")
✅ 正确做法:
1. 使用列表推导式
2. 使用类型提示
3. 遵循 PEP 8
4. 编写 docstring
❌ 错误做法:
1. 使用传统 for 循环
2. 省略类型提示
3. 忽略代码风格
4. 不写文档
✅ 正确做法:
1. 使用 EAFP 风格
2. 只捕获特定异常
3. 记录异常信息
4. 清理资源(finally 或 context manager)
❌ 错误做法:
1. 捕获所有异常 (except:)
2. 忽略异常信息
3. 不释放资源
✅ 正确做法:
1. 为函数添加返回类型
2. 为公共 API 添加类型
3. 使用 Optional 处理 None
4. 使用 Union 处理多种类型
❌ 错误做法:
1. 完全不使用类型提示
2. 使用 any 类型
3. 类型提示与实现不一致
Terminal window
# 代码检查
ruff check .
pylint .
flake8 .
# 代码格式化
black .
ruff format .
# 类型检查
mypy .
pyright .
# 运行测试
pytest
# 代码质量
pylint --rcfile=pylintrc mymodule.py

不使用类型提示

错误:Python 是动态类型,不需要类型提示 正确:类型提示提高可读性和 IDE 支持

过度使用异常

错误:用异常处理控制流程 正确:异常只用于异常情况

忽略 PEP 8

错误:代码能跑就行 正确:遵循代码风格指南

使用可变默认值

错误:def f(a=[]): … 正确:def f(a=None): if a is None: a = []

何时使用

  • 编写新 Python 代码
  • 审查 Python 代码
  • 重构现有代码
  • 设计 Python 包

何时不用

  • 一次性脚本
  • 快速原型
  • 学习实验

关键要点

  • 可读性优先
  • 显式优于隐式
  • EAFP 风格
  • 组合优于继承

常见错误

  • 忽略 PEP 8
  • 不使用类型提示
  • 过度使用异常
  • 可变默认参数

Pythonic 不仅仅是语法技巧,而是一种思维方式:

  1. 简洁 - 用最少的代码表达最多的意思
  2. 清晰 - 代码读起来像英文
  3. 高效 - 利用 Python 的特性而非对抗
  4. 一致 - 遵循社区约定
  • 缩进:4 空格
  • 行长度:最大 79 字符
  • 命名:snake_case 函数/变量,CamelCase 类
  • 导入:标准库、第三方、本地,按组排序
  • 静态分析:在运行前发现错误
  • IDE 支持:自动补全和重构
  • 文档作用:代码即文档
  • 类型安全:减少运行时错误
技能关系
python-testing测试驱动开发
code-review代码审查
tdd-workflowTDD 工作流
  1. 安装工具 - pip install ruff mypy black
  2. 配置 - 创建 pyproject.toml
  3. 编写代码 - 遵循 PEP 8 + 类型提示
  4. 检查 - ruff check . && mypy .
  5. 格式化 - ruff format .

官方原文: python-patterns SKILL.md


💡 提示:代码是写给人看的,顺便能在机器上运行。