# Python 核心速查

Source: https://codewiki.com/zh/cheatsheets/python/

## 绑定与分支

- `name = value` — 绑定或重新绑定名称，不复制对象
- `first, *middle, last = values` — 解包时把中间元素收集到新列表
- `result = value if condition else fallback` — 只求值并返回选中的分支
- `if (match := pattern.search(text)):` — 只求值一次，同时保留匹配对象
- `match command:` — 从上到下用各个 `case` 匹配一次求值的对象
- `case {'action': action, **rest}:` — 捕获一个映射值和其余未匹配的键值

## 集合

- `items[start:stop:step]` — 选取序列切片，不修改原序列
- `[project(item) for item in items if keep(item)]` — 筛选并转换为新列表
- `{key(item): value(item) for item in items}` — 用生成的键值对构造字典
- `unique = set(items)` — 对可哈希值去重，不保留输入顺序
- `mapping.get(key, fallback)` — 只在键不存在时返回后备值
- `sorted(items, key=key_fn, reverse=True)` — 按派生键排序并返回新列表

## 函数与作用域

- `def fetch(url, /, timeout=5, *, retries=2):` — 把 `url` 限定为仅限位置参数，把 `retries` 限定为仅限关键字参数
- `def collect(*items, **options):` — 收集额外的位置参数和关键字参数
- `result = function(*args, **kwargs)` — 把可迭代对象和映射解包为调用参数
- `nonlocal count` — 重新绑定最近一层外部函数中的绑定
- `@functools.wraps(function)` — 复制被包装函数的元数据，并公开其引用
- `@functools.cache` — 按可哈希参数缓存调用结果，不限制缓存大小

## 对象与抽象基类

- `from abc import ABC, abstractmethod` — 导入定义抽象基类所需的辅助对象
- `class Service(ABC):` — 声明由 `ABCMeta` 管理的类
- `@abstractmethod` — 要求具体子类覆盖所标记的方法
- `super().__init__()` — 调用方法解析顺序中的下一个初始化方法
- `@dataclass(slots=True, frozen=True)` — 生成使用槽且禁止字段赋值的数据类
- `items: list[str] = field(default_factory=list)` — 为每个数据类实例创建新列表

## 迭代与惰性管道

- `enumerate(items, start=1)` — 为每个元素配上从一开始的计数
- `zip(left, right, strict=True)` — 可迭代对象长度不同时抛出 `ValueError`
- `(project(item) for item in items)` — 创建惰性的生成器表达式
- `yield from source` — 委托迭代和生成器协议操作
- `itertools.islice(source, start, stop)` — 惰性选取迭代器切片
- `itertools.chain.from_iterable(groups)` — 惰性展开一层可迭代对象

## 错误与清理

- `raise ValueError(message)` — 明确拒绝无效值
- `raise DomainError(message) from error` — 把原始失败保留为直接原因
- `except (ValueError, TypeError) as error:` — 只捕获列出的异常类型
- `with open(path, encoding='utf-8') as stream:` — 退出代码块时关闭文本流
- `with contextlib.suppress(FileNotFoundError):` — 只忽略代码块中指定的异常
- `with contextlib.ExitStack() as stack:` — 按相反顺序释放数量动态变化的资源

## 异步与并发

- `asyncio.run(main())` — 运行一个顶层协程并关闭其事件循环
- `result = await coroutine()` — 挂起当前任务，直到可等待对象完成
- `async with asyncio.TaskGroup() as group:` — 退出作用域前等待所有子任务
- `task = group.create_task(work())` — 启动一个由任务组管理的协程
- `async with asyncio.timeout(5):` — 把代码块内的等待限制为五秒
- `result = await asyncio.to_thread(blocking_call)` — 把阻塞式 I/O 移出事件循环线程

## 路径与进程

- `path = Path('data/config.toml')` — 构造路径，不访问文件系统
- `text = path.read_text(encoding='utf-8')` — 读取并解码文本文件，然后将其关闭
- `path.write_text(text, encoding='utf-8')` — 覆盖并编码文本文件，然后将其关闭
- `path.mkdir(parents=True, exist_ok=True)` — 幂等地创建缺失的父目录
- `result = subprocess.run(args, check=True, text=True, capture_output=True)` — 捕获文本输出，并在退出状态非零时抛出异常
- `with tempfile.TemporaryDirectory() as directory:` — 退出代码块时删除临时目录

## 数据边界

- `data = json.loads(text)` — 把 JSON 文本解析为 Python 值
- `text = json.dumps(data, ensure_ascii=False)` — 序列化为 JSON，不转义非 ASCII 字符
- `with path.open(newline='', encoding='utf-8') as stream:` — 让 CSV 模块正确处理字段内换行
- `rows = csv.DictReader(stream)` — 把每条 CSV 记录读取为以表头为键的映射
- `digest = hashlib.sha256(payload).hexdigest()` — 哈希字节，并以十六进制文本返回摘要
- `token = secrets.token_urlsafe(32)` — 用 32 个随机字节生成 URL 安全令牌

## 文本与时间

- `clean = ' '.join(text.split())` — 清除首尾空白，并把连续空白压成一个空格
- `match = re.fullmatch(r'[A-Z]{2}\d{4}', text)` — 要求正则表达式匹配整个字符串
- `block = textwrap.dedent(block)` — 移除非空行共有的缩进
- `now = datetime.now(timezone.utc)` — 创建带时区信息的当前 UTC 日期时间
- `stamp = datetime.fromisoformat(text)` — 解析受支持的 ISO 8601 日期时间字符串
- `local = now.astimezone(ZoneInfo('Europe/Paris'))` — 把同一时刻转换到 IANA 时区

## 类型提示

- `name: str = value` — 为静态工具标注绑定，不在运行时强制检查
- `def parse(text: str) -> int:` — 标注参数类型和返回类型
- `type Result[T] = T | Exception` — 声明泛型类型别名
- `def first[T](items: Sequence[T]) -> T:` — 声明带一个类型参数的泛型函数
- `class Reader(Protocol):` — 描述供静态检查使用的结构化接口
- `class Config(TypedDict):` — 描述字典应有的键和值

## 测试与本地工具

- `python -m venv .venv` — 创建隔离的虚拟环境
- `python -m unittest -v` — 详细输出自动发现并运行的标准库测试
- `python -m pdb script.py` — 在 Python 调试器中启动脚本
- `breakpoint()` — 在配置的调试器钩子处暂停
- `python -m compileall src` — 把源文件预编译为字节码
- `python -m timeit 'sum(range(1000))'` — 重复运行并测量一条简短语句
