Imported from comet-7x/python-cookbook (
AGENTS.md). Install upstream withnpx skills add comet-7x/python-cookbook. Copyright stays with the author.
python-cookbook
Python 学习项目,按主题拆解、由浅入深地演示 Python 的基础语法与高级语法。
每个示例都是独立可运行的 .py 脚本,配合中文注释边跑边学。
目录结构
# 基础语法:src/ 下 12 个章节目录(NN_主题.py 编号)
# 每章含 README.md 导读(章节第一站,见下「章节导读」节)
src/getting_started/ 1. 入门
src/operators/ 2. 运算符
src/data_types/ 3. 数据类型
src/control_flow/ 4. 控制流
src/functions/ 5. 函数
src/classes/ 6. 类
src/modules/ 7. 模块(含 fibonacci_module / sound_package 示例模块)
src/exceptions/ 8. 异常
src/files/ 9. 文件(含示例数据文件)
src/additions/ 10. 补充
src/standard_libraries/ 11. 标准库速览(含 glob_files 示例文件)
src/user_input/ 12. 用户输入
# 高级主题
src/multithreading_and_multiprocessing/ 并发与多进程(高级主题)
├── threading/ 线程:从创建基础到同步原语(Lock/RLock/Condition/...)
└── processing/ 进程:内存隔离 / 共享对象 / IPC / 进程池 / Actor 模式
顶层
temp/仅用于临时试验,不纳入正式示例。
代码组织约定
- 编号即教学顺序:文件名以
NN_主题.py命名,NN决定讲解先后, 读者按编号顺序阅读即可形成递进(如threading/01_thread_basics.py→07_condition.py)。 - 一个文件一个主题:每个脚本聚焦一个知识点,自带
if __name__ == "__main__":演示入口。 - 场景化叙事:契合业务语境的示例(尤其并发部分)统一使用一套贴合业务的人物/场景 (「面试系统」:候选人、面试官、考察进程、调度中心、HR 主进程);纯语法点(位运算、 类型转换等)用中性数据,不强行套场景,让抽象概念有画面、便于记忆。
- 对照式教学:能形成对比的知识(如「加锁 vs 不加锁」「线程池 vs 进程池」) 尽量放在同一文件内并列运行,让读者直观看到差异与数据。
章节导读(重要 · 全项目统一)
每个章节目录都有一个 README.md,是该章的「第一站」:读者进章先读它,
像看一份目录导读——本章讲什么、文件按什么顺序读、每个文件学什么,
需要时直接链接到本章的代码/文档。读完导读再按编号顺序进具体文件,形成「总览 → 细读」。
src/multithreading_and_multiprocessing/ 下 threading 与 processing 两个子目录各算一章。
README.md 固定构成(顺序固定)
- 标题:
# 第 N 章 章名 / 英文名(并发两章用# 高级 · 线程等,不占 12 章序号)。 - 一句话导读(引用块
>):本章解决什么问题、学完能干什么。 - 本章文件清单:一张表,
| 编号 | 文件 | 你将学到 |,文件列必须是可跳转链接 ([NN_name.py](NN_name.py)同目录相对路径),编号与文件名逐字核对磁盘实际文件, 不许凭记忆写。支撑文件(如fibonacci_module.py、sound_package/、candidates.txt) 单列一行注明"非编号、被本章示例引用"。 - 本章学习目标:3~5 条,
1.编号的可自测问题/能力(复用「学习闭环」构件 1 口径, 但上升到"整章学完"的粒度)。 - 上一章 / 下一章:各一个链接。基础 12 章串成环(12 → 1 不连,12 的下一章指向 并发 threading);并发 threading ↔ processing 互链,processing 的下一章写"全书完"。
单一数据源规则(防链接腐烂)
各章文件清单的权威版本只放在该章 README.md 里;根 README.md 与
docs/README_zh.md、docs/README_en.md 不再逐文件列表,每章只保留一句定位
- 一个指向该章
README.md的链接(跨章"地图"职责下沉到各章导读)。 改文件名 / 增删文件时:只改对应章README.md的文件清单 + 该章内代码里对彼此的引用, 不要再维护第二份清单。提交前用grep -rn "旧文件名"确认全仓无残留引用。
第一章特例:
README.md本身承担"什么是 Python"的介绍内容(00 号), 其余章节 README 保持"纯导读"、不承载知识点正文。
学习闭环(重要 · 全项目统一)
学习不只是输入。每个文件都要让读者「读代码 → 预测 → 运行核对 → 动手破坏 → 回答思考题」。 新手读完跑完如果没有任何输出(自己的话),就等于没学。每个脚本因此带两个固定构件:
构件 1:文件 docstring 里的「学习目标」
文件级 docstring 第二块固定为「学习目标」(3~4 条, 1. 缩进编号)。
写的是可自测的问题/能力(「应能回答:join 是'谁在等谁'」),不是内容清单
(❌「本文件演示 start/join」——那是流水账,读者学完没法自查)。
构件 2:文件末尾的「运行后思考」块
每个可运行脚本的最后一行是 3 题思考块(纯注释,不影响运行;.md 文末用同级标题)。 三题类型固定、各司其职:
# ═══════════ 运行后思考(答案都在上面的输出里,2 分钟) ═══════════
# Q1(预测):运行前你能预测 ____ 是多少吗?回上面输出找答案,和你想的一致吗?
# Q2(破坏):把 L__ 的 `xxx` 注释掉再跑一次,输出哪里变了?为什么?
# Q3(连接):____ 其实就是下一章 __/___py 的主角,它还会怎样?
- Q1 预测题:必须指向本文件真实输出里能看到的某个值/现象,让读者用"预测 vs 实际"
制造记忆点;非直觉的输出(
0.30000000000000004、257 is 257 → False)优先选。 - Q2 破坏题:必须真可执行——注释掉一行/改一个数字再跑,观察差异。写题的人 必须先实测破坏后的输出,确认差异真实存在且值得看,不许凭想象出题。
- Q3 连接题:把本文件的概念接到具体的下一文件/前一章(写真文件名), 让知识成网而不是散点。没有前后关联的孤立文件改问"这个知识在 场景 里会怎么用"。
- 答案不写进注释:Q1/Q2 的答案从输出即可看出;涉及仓库外知识的题目可加半行
(提示:xxx)。 - 题目一律中文、不用 emoji;每行 ≤100 字符;块标题格式固定(
# ═══════════ 运行后思考…)。 - 思考块放在
if __name__演示代码之后、文件最末尾。
注释风格(重要 · 全项目统一)
形式统一:docstring 优先;内容只讲「为什么」。
形式
- 文件头一律用文件级 docstring:每个可运行脚本以
"""章节 · 主题\n\n一句话点出本文件演示什么、读者该学到什么。"开头, 再进入 import / 代码。禁止用文件头注释堆砌(# 本文件演示…)替代。 - 类与函数保留 docstring:一句话说清「这个类/函数是干什么的」,
需要时补 Args/Returns。它们是 API 文档,
inspect可读,是 Python 惯例——保留。 - 行内注释用
#:贴在具体语句旁,解释非直觉的局部行为。 - 需要分块时(少用),用
# ======分隔区块标题,不用它替代文件 docstring。
内容(核心)
删掉无信息的,但保留学习者需要的。注释的第一读者是零基础、单独读这一个文件的人, 宁可保守,不要为了"看起来干净"而删信息。
- 删掉无信息量的:纯流水账、只把变量名再念一遍的。
反例:
# 导入 time 模块/# 定义一个变量/# 创建候选人列表 candidates。 - 该留的四类(教学项目专用,看着像 what,其实是 why 或预期验证):
- 预期输出:
print(0xFF) # 255、print(0.1 + 0.2) # 0.30000000000000004。 学习者运行代码时靠它核对"和我想的一致吗";非直觉的结果更要写。 - 逐符号/方法的语义:
print(backend & frontend) # 交集 {张三}、scores.append(85) # 末尾追加、f.seek(0) # 回到文件开头。 语法点文件里一个符号就是一条知识点,不能因为"方法名看起来明白"就省。 - 对照锚点:对比演示中标注两行输出差异的,
# 6 6→# 8 6、# 每次都是全新列表—— 读者靠它发现"从哪一行开始不一样的"。 - 隐藏的行为与坑:非直觉行为、设计取舍、平台差异、数值来源、
为什么要这样写。正例:
# 面试是耗时操作,必须在锁外执行,否则 Condition 退化成普通锁。
- 预期输出:
- 每条注释尽量一行说清;文件/函数 docstring 顶部允许 2~3 行区块说明。
- 注释贴在被解释的语句上,不写成长段旁白。
自问法则:写完每条注释先问「一个零基础的人只读这一个文件,删掉它我会卡住吗?」 会 → 留(哪怕它在解释 what);不会 → 删。拿不准时,留。
常用命令
uv sync --dev # 安装开发依赖(ruff + pyright)
uv run ruff check --fix . # 代码检查 + 自动修复
uv run ruff format . # 格式化(line-length 100,适配中文注释)
uv run pyright # 类型检查(与编辑器里的 Pylance 同源同配置)
改动代码后,提交前请确保 ruff check、ruff format --check、pyright 三项均通过。
关于类型检查的红线
编辑器里的 Pylance 和命令行的 pyright 是同一个引擎,配置统一写在
pyproject.toml 的 [tool.pyright](typeCheckingMode = "standard"),
所以「IDE 爆红但命令行全绿」不应该出现;若出现,先检查 VS Code 选中的
解释器是不是本项目的 .venv。
本仓库有一类特殊情况:故意写错的反面教材(如 09_annotations 传 str 当 int 演示"注解不强制"、07_multiple_inheritance 演示 MRO 冲突)。这些代码是对的, 红的是教学意图。处理原则:
- 不要为了消红而改掉演示代码——那会毁掉这一课。
- 在该行加
# pyright: ignore[具体规则名],并用注释写明"为什么是故意的"。 - 只在整篇都围绕该行为时才用文件级
# pyright: 规则名=false(如 01_definition 整篇讲动态挂属性),且必须同时写明正式项目里应该怎么写。 - 严禁裸
# type: ignore或全局关规则——那是把真 bug 一起藏起来。