11 / 90

Day 11: 异常与隔离环境

只捕获你预期的异常,用 with 和 finally 保证清理,并在全新的虚拟环境中复现“在我机器上能跑”的故障——先诊断,再动手。 Retrieval and lower-new-content review are part of the 480-minute ledger.

Self-Directed Learning & Python 480 active minutes (8 hours focused study)
01 120 分钟

精确的异常处理与有保证的清理

仅在记录预测和观察到的证据之后,才允许使用辅助。

Prerequisites

完成上一项活动;如遇阻塞,使用所列恢复链接。

Learning Objective

预测文件打开成功与抛出 FileNotFoundError 时 try、except、else、finally 各执行哪些子句,然后验证。把手动 close() 换成 with 块,并解释为什么禁止裸 except。

Instructions

try 放有风险的调用。except FileNotFoundError as e 只处理这一种预期失败,e.filename 给出缺失路径。else 只在无异常时运行;finally 总是运行。裸 except: 被禁止,因为它连 KeyboardInterrupt 和真正的程序错误也会吞掉,让诊断变成瞎猜。对文件对象来说,with 是预定义的清理动作,有了它 finally 就不再必要。

Practice & Prediction Log

在一个空的临时文件夹中操作。把这个脚本运行两次:第一次 notes.txt 不存在,第二次先用 printf 'hi\n' > notes.txt 创建它再运行。

try:
    f = open("notes.txt", encoding="utf-8")
except FileNotFoundError as e:
    print("cannot open", e.filename)
else:
    print("opened", f.name)
    f.close()
finally:
    print("cleanup")

每次运行前,写下 try / except / else / finally 中哪些会执行以及确切输出。然后 (1) 改写成用 with 块关闭文件,取代 else + f.close(),并展示块结束后 f.closed 为 True;(2) 举出裸 except: 会隐藏的两样东西。

Independent Mastery Criterion

能准确说出成功与失败各执行哪些子句,正确把 else/close() 改成 with 块,并举出裸 except 会隐藏的两样东西。

Authoritative Source Resources & Provenance

linking PSF License Version 2

The Python Tutorial: Errors and Exceptions

作者 / 机构: Python Software Foundation | 原始出处链接 ↗

对应章节 / 时间戳: Sections 8.3–8.6 (handling exceptions, else, finally, cleanup actions)

验证版本与日期: Python 3.12 documentation; verified 2026-10-30

入选理由:

Primary reference for try/except/else/finally semantics and the with statement as predefined cleanup.

来源前置条件:

安全回退方案(离线弹性):

Every clause behavior in the lesson is demonstrated by runnable local snippets.

对比候选资源与选型分析 (2)
MIT OCW 6.0001 Lecture on Exceptions ↗ compared_alternative [CC BY-NC-SA 4.0]

Solid lecture treatment, but paced for a semester course and requires video viewing; the tutorial section matches the exercise scope directly.

Python Standard Library: Built-in Exceptions ↗ compared_alternative [PSF License Version 2]

Reference-style exception hierarchy listing rather than the tutorial narrative; retained as lookup material for the recovery drills.

02 120 分钟

故障诊所:从 traceback 到定点修复

仅在记录预测和观察到的证据之后,才允许使用辅助。

Prerequisites

完成上一项活动;如遇阻塞,使用所列恢复链接。

Learning Objective

拿到一个在畸形分数行上崩溃的脚本,自下而上读 traceback,指出故障行与异常类型,并应用最小修复:在 int() 周围做定点 except ValueError,而不是包整个程序的捕获。

Instructions

traceback 按调用从最旧到最新排列;最后一行给出异常类型和消息:ValueError: invalid literal for int() with base 10: 'x9',其上方的帧指向 total += int(raw) 这一行。先用那一条坏行复现崩溃。最窄的修复只把 int(raw) 包进 try/except ValueError,记录行号后继续。把整个程序包进 except Exception 会藏住无关缺陷,还会把它们误报成数据错误。

Practice & Prediction Log

在一个空的临时文件夹中创建诊所数据:

printf 'ana,7\nbo,x9\ncy,5\n' > scores.csv

把下面的代码保存为 clinic.py:

total = 0
with open("scores.csv", encoding="utf-8") as fh:
    for lineno, line in enumerate(fh, start=1):
        name, raw = line.strip().split(",")
        total += int(raw)
print("total", total)

运行 python3 clinic.py,自下而上阅读 traceback。记录诊断:故障行、异常类型和最窄的修复。然后修改 clinic.py 让它运行到结束,打印有效行的总和以及被跳过的行号。

Independent Mastery Criterion

诊断写明故障位置与异常类型,依据异常层次解释所选 except 类型为何是最窄的正确类型,并展示程序带着跳过报告运行到结束。

Authoritative Source Resources & Provenance

linking PSF License Version 2

Python Standard Library: Built-in Exceptions

作者 / 机构: Python Software Foundation | 原始出处链接 ↗

对应章节 / 时间戳: Concrete exceptions and Exception hierarchy

验证版本与日期: Python 3.12 documentation; verified 2026-10-30

入选理由:

Normative hierarchy used to justify the narrowest correct except clause during diagnosis.

来源前置条件:

安全回退方案(离线弹性):

The clinic traceback is reproduced locally; help(ValueError) documents the hierarchy offline.

对比候选资源与选型分析 (2)
W3Schools Python Exceptions ↗ compared_rejected_for_day11 [Proprietary]

Encourages broad except blocks; the clinic instead requires naming the exact hierarchy level.

The Python Tutorial: Errors and Exceptions ↗ compared_alternative [PSF License Version 2]

Friendlier first-pass narrative; the library reference was selected for the normative hierarchy the exercises name directly.

03 120 分钟

用 venv 搭建隔离环境

仅在记录预测和观察到的证据之后,才允许使用辅助。

Prerequisites

完成上一项活动;如遇阻塞,使用所列恢复链接。

Learning Objective

在一个一次性的临时文件夹中,用 python3 -m venv --without-pip .venv 创建虚拟环境,用 sys.executable 证明其解释器与 python3 不同,展示只装进 venv 的模块对 python3 不可见,并把依赖记录到 requirements.txt。

Instructions

只在一次性文件夹中操作,这样观察到的每个差异都是你亲手制造的,而不是对自己机器的假设。命令适用于 Linux/macOS shell(Windows 上解释器是 .venv\Scripts\python.exe;此处未执行)。不要激活 venv:按路径调用每个解释器。

使用专用的一次性 shell/会话。搭建和之后的所有步骤都在同一个 shell 中运行。搭建中任何一步失败都会退出该 shell;不要继续。每次打开新 shell 都必须重新运行搭建代码块。搭建后,继续之前确认 pwd 显示的是 $work。

work=$(mktemp -d) &&
cd "$work" &&
python3 -m venv --without-pip .venv || exit 1

之后的所有步骤都在同一个 shell 中运行;如果 echo "$work" 没有输出,先重新运行搭建代码块。--without-pip 让创建过程无需联网;新 venv 只带标准库。sys.executable 给出实际正在运行的解释器。sysconfig.get_path('purelib') 给出该解释器的 site-packages 文件夹(已安装模块所在处),所以把一个单文件模块复制进去,就是一次无需网络、无需第三方包的手工安装。这只是教学用的捷径,并非 pip 的做法:pip 还会写入安装元数据(.dist-info 文件夹),因此 pip 不会记录这份手工复制,也无法卸载它。venv 的 pyvenv.cfg 写着 include-system-site-packages = false:它不读取基础解释器的 site-packages,其他解释器也不读取 venv 的。依赖以固定版本行写进 requirements.txt(绝不放凭据),绝不提交 .venv。完成后:cd / && rm -rf "$work"。

Practice & Prediction Log

在 $work 中,运行前先预测每个结果。第 1 步:运行的是哪个解释器?

python3 -c "import sys; print(sys.executable)"
.venv/bin/python -c "import sys; print(sys.executable)"

第 2 步:新建的 venv 能导入 day11_helper 吗?

.venv/bin/python -c "import day11_helper"

第 3 步:把一个单文件模块只装进 venv,然后在其中导入:

site=$(.venv/bin/python -c "import sysconfig; print(sysconfig.get_path('purelib'))")
printf 'def label():\n    return "helper from the venv"\n' > "$site/day11_helper.py"
.venv/bin/python -c "import day11_helper; print(day11_helper.label())"

第 4 步:python3 能导入它吗?

python3 -c "import day11_helper"

第 5 步:隔离证据,以及这个 venv 里有没有 pip:

grep include-system-site-packages .venv/pyvenv.cfg
.venv/bin/python -c "import sys; print(sys.prefix != sys.base_prefix)"
.venv/bin/python -m pip --version

第 6 步:记录一个练习用的钉版(不要安装;那需要 pip 和包索引):

printf 'packaging==24.1\n' > requirements.txt
cat requirements.txt

针对第 2 步和第 4 步记录诊断:应该改 import 行,还是改变环境?

Independent Mastery Criterion

能证明两个解释器路径不同,在新建 venv 中复现 ModuleNotFoundError,并在模块只装进 venv 后于 python3 下再次复现,且能根据 pyvenv.cfg 和 sys.prefix 解释 venv 与其他解释器为何互相看不到对方的 site-packages。

Authoritative Source Resources & Provenance

linking PSF License Version 2

The Python Tutorial: Virtual Environments and Packages

作者 / 机构: Python Software Foundation | 原始出处链接 ↗

对应章节 / 时间戳: Section 12 (Virtual Environments and Packages; creating venvs, pip, requirements)

验证版本与日期: Python 3.12 documentation; verified 2026-10-30

入选理由:

Primary reference for python -m venv, interpreter isolation, and requirements files.

来源前置条件:

安全回退方案(离线弹性):

The drill needs no network: venv creation, sys.executable inspection, and ModuleNotFoundError reproduction all run offline.

对比候选资源与选型分析 (2)
pip documentation ↗ compared_alternative [MIT]

Primary reference for pip commands, but the tutorial section covers the create-activate-install loop as one narrative better suited to beginners.

virtualenv documentation ↗ compared_alternative [MIT License]

Mature third-party environment tool with overlapping behavior; the stdlib venv tutorial was selected to avoid an extra dependency for first-time setup.

04 120 分钟

错误环境诊断演练

独立掌握检查(无 AI 辅助)。

Prerequisites

完成上一项活动;如遇阻塞,使用所列恢复链接。

Learning Objective

独立诊断一个只在两个受控解释器之一下以 ModuleNotFoundError 失败的脚本,给出 sys.executable 与 find_spec 证据及最小环境修复,然后把一次文件读取包进精确的 except 子句。

Instructions

闭卷。严格按下面搭建夹具;它保证只有 good 这个 venv 拥有该依赖(Linux/macOS shell,无需网络,无需第三方包):

使用专用的一次性 shell/会话。搭建和之后的所有步骤都在同一个 shell 中运行。搭建中任何一步失败都会退出该 shell;不要继续。每次打开新 shell 都必须重新运行搭建代码块。搭建后,继续之前确认 pwd 显示的是 $work。

work=$(mktemp -d) &&
cd "$work" &&
python3 -m venv --without-pip good &&
python3 -m venv --without-pip .venv &&
good_site=$(good/bin/python -c "import sysconfig; print(sysconfig.get_path('purelib'))") &&
printf 'def label():\n    return "report ok"\n' > "$good_site/day11_helper.py" &&
printf 'import day11_helper\nprint(day11_helper.label())\n' > report.py || exit 1

之后的所有步骤都在同一个 shell 中运行;如果 echo "$work" 没有输出,先重新运行搭建代码块。症状:.venv/bin/python report.py 抛出 ModuleNotFoundError: No module named 'day11_helper',而 good/bin/python report.py 正常。任务 1:从两个解释器收集证据(运行的是哪个解释器、能否找到 day11_helper),记录诊断,应用最小修复,并展示之后 .venv/bin/python report.py 打印 report ok。任务 2:编写 read_text(path),在 try/except FileNotFoundError 内以 encoding="utf-8" 打开 path,文件缺失时打印 missing 和 e.filename 而不是崩溃。完成后:cd / && rm -rf "$work"。

Practice & Prediction Log

记录:(a) 两个 sys.executable 值;(b) 每个解释器能否找到 day11_helper;(c) 在 .venv/bin/python 下复现的 ModuleNotFoundError;(d) 诊断类别:代码故障还是环境故障;(e) 修复以及证明修复生效的输出;(f) 你的 read_text 函数及其对 no_such_file.txt 的输出。

Independent Mastery Criterion

独立完成:诊断基于证据(来自两个解释器的 sys.executable,以及 find_spec 或 ModuleNotFoundError),修复针对这些证据所确定的原因并以 report ok 证明,文件读取恰好使用 except FileNotFoundError。

Authoritative Source Resources & Provenance

linking PSF License Version 2

The Python Tutorial: Virtual Environments and Packages

作者 / 机构: Python Software Foundation | 原始出处链接 ↗

对应章节 / 时间戳: Section 12 (Virtual Environments and Packages; creating venvs, pip, requirements)

验证版本与日期: Python 3.12 documentation; verified 2026-10-30

入选理由:

Reference retained for the independent wrong-environment diagnosis assessment.

来源前置条件:

安全回退方案(离线弹性):

The assessment reproduces ModuleNotFoundError with the local interpreter only.

对比候选资源与选型分析 (2)
pip documentation ↗ compared_alternative [MIT]

Reference for install commands if the learner chooses the install-based fix.

virtualenv documentation ↗ compared_alternative [MIT License]

Mature third-party environment tool with overlapping behavior; the stdlib venv tutorial was selected to avoid an extra dependency for first-time setup.