恢复演练:诊断失败的环境
独立掌握检查 — 评估作业期间不得使用 AI 辅助。如接受任何辅助必须如实申报,但接受辅助的作业只计为补救练习:在声称掌握之前,必须完成一次新的无辅助检查。
前置要求
完成第 02 学习日各活动。评估路径需要 Bash;已验证的执行范围是 Linux Bash。需要可用的 `python3`;不安装软件包、不做机器级更改。
学习目标
用预测、最小复现和恢复笔记,诊断一个被故意破坏的虚拟环境或路径假设。
操作指引
本演练在一次性 env-drill 目录内提供一个故意破坏但无害的装置。运行前预测症状,复现它,收集诊断证据,应用可论证的最小修正,然后复查。全程留在装置目录内;不做任何机器级更改(不安装、不编辑 env-drill 以外的内容、不做持久环境改动——下面的修复只作用于单次命令调用)。 各代码块在失败即停的子 shell 中运行:设置阶段先验证新建的 mktemp 私有根目录,失败会在写入前中止;还会通过一个不执行模块代码的 importlib.util.find_spec 检查来确认环境 Python 配置是否已能解析 helper,若能解析也会中止(预期失败需要这一前提;该探针不导入也不运行模块)。最后的代码块会打印一条字面 rm -r -- <private-root> 清理行,只指向所创建的根目录。后续代码块之前先粘贴打印的 export SBX_ROOT= 行;并记录shell 原本 PYTHONPATH 的设置与否及其取值——未设置、空、非空都是有效证据。 请在 Bash 中运行这些代码块——打印的 export/rm -r -- 行使用 Bash 的 %q 引用,实际执行范围为 Linux Bash;zsh/dash/Windows 未执行。
自主演练与记录
构建损坏的装置并复现失败(整块粘贴;若设置失败,或不执行模块的检查发现 helper 已可解析,会在写入前中止):
(
set -e
SBX_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/d03env.XXXXXX")
[ -n "$SBX_ROOT" ]
[ -d "$SBX_ROOT" ]
[ -w "$SBX_ROOT" ]
[ -x "$SBX_ROOT" ]
probe_rc=0
python3 -c "import sys, importlib.util
try:
spec = importlib.util.find_spec('helper')
except Exception:
sys.exit(4)
sys.exit(3 if spec is not None else 0)" || probe_rc=$?
if [ "$probe_rc" -ne 0 ]; then
if [ "$probe_rc" -eq 3 ]; then
echo "abort: ambient Python config already resolves 'helper' - the intended failure cannot be demonstrated"
else
echo "abort: helper-resolvability probe failed (rc=$probe_rc) - cannot verify the precondition safely"
fi
exit 1
fi
mkdir "$SBX_ROOT/env-drill"
cd "$SBX_ROOT/env-drill"
mkdir tools
printf 'def greet():\n return "ok"\n' > tools/helper.py
printf 'from helper import greet\nprint(greet())\n' > app.py
rc=0
python3 app.py 2>err.txt || rc=$?
cat err.txt
grep -q "ModuleNotFoundError: No module named 'helper'" err.txt
echo "expected failure observed (rc=$rc)"
printf 'export SBX_ROOT=%q\n' "$SBX_ROOT"
)
运行前预测错误。粘贴打印的 export SBX_ROOT= 行,然后收集证据:
(
set -e
: "${SBX_ROOT:?run the setup block first, then paste its printed export line}"
[ -d "$SBX_ROOT/env-drill" ]
cd "$SBX_ROOT/env-drill"
python3 -c "import sys, os; print([os.path.abspath(p or '.') for p in sys.path])"
ls tools
)
仅对本次调用应用可论证的最小修正并复查,将 PYTHONPATH 与记录的原始值比较——代码块会打印明确的 set/unset 标记和取值,因此未设置、空、非空的原始状态都可区分地证明未改变:
(
set -e
: "${SBX_ROOT:?run the setup block first, then paste its printed export line}"
[ -d "$SBX_ROOT/env-drill" ]
cd "$SBX_ROOT/env-drill"
pp_state() { if [ "${PYTHONPATH+x}" = x ]; then printf 'PYTHONPATH %s: set value=<%s>\n' "$1" "$PYTHONPATH"; else printf 'PYTHONPATH %s: unset\n' "$1"; fi }
pp_state before
PYTHONPATH=tools python3 app.py
pp_state after
printf 'rm -r -- %q\n' "$SBX_ROOT"
)
记录症状、证据、修复、为何最小的理由,以及复查结果。
Python 按 sys.path 搜索——python3 app.py 时是脚本所在目录,python3 -c 时是当前目录。tools/ 两者都不在,所以 from helper import greet 无法解析。PYTHONPATH=tools 只为那一次调用添加路径;pp_state 行会打印明确的 set/unset 标记和取值,据此对比前后输出以确认没有持久化。PYTHONPATH 可以未设置、为空或已有值——三种情况下不变都证明无持久化。它是导入搜索变量,与可执行文件 PATH 无关。
观察结果(Linux,Python 3.14):
1. 症状:ModuleNotFoundError: No module named 'helper' — env-drill 在 sys.path 上,而 env-drill/tools 不在。
2. 证据:解析后的 sys.path 列表显示 env-drill 和标准库——没有 env-drill/tools;ls tools 显示 helper.py 存在——文件在,但从脚本位置不可导入。
3. 可论证的最小修复:PYTHONPATH=tools python3 app.py → ok。只为这次调用修正导入路径——不改文件、不留持久环境改动(PYTHONPATH 前后输出为记录的原始值——未设置、空或相同的非空值;不变即证明无持久化)。移动 app.py 或编辑文件都会改动过多。预期失败还依赖一个环境前提,设置代码块不运行模块即可检查并在不满足时中止:helper 必须尚未可解析——importlib.util.find_spec 探针不导入也不执行它(环境 PYTHONPATH 或 site-package 可能已能解析它)。
4. 复查:输出 ok;装置其余部分不变。
Windows 参考信息(未执行,也不是等价的限定写法):cmd set PYTHONPATH=tools && python app.py 与 PowerShell $env:PYTHONPATH='tools'; python app.py 会为整个会话设置变量——要声称无持久化必须事后还原;单次调用限定需要另外的写法。此处未验证。
在无辅助条件下满足以下全部即通过:(a) 运行前预测了 `ModuleNotFoundError` 症状;(b) 记录了诊断证据(缺少 `tools/` 的解析后 `sys.path` 列表,以及显示文件存在的 `ls tools` 结果);(c) 所应用的修复限定在单次调用内,并书面说明了为何最小;(d) 记录了成功的复查和无持久化检查——限定修复后的 `PYTHONPATH` 与记录的原始值(未设置、空、或不变的非空值)一致。辅助只计为补救练习,在声称掌握之前必须完成一次新的无辅助检查。
权威源资源与权利证明
The Python Tutorial: Virtual Environments and Packages
对应章节 / 时间戳: Section 12 (creating venvs, pip installs, requirements files)
验证版本与日期: Python 3.12 (Verified: 2026-10-30)
Primary reference for python -m venv, interpreter isolation, and requirements files used by the wrong-environment drills.
Basic Python syntax from Study Days 01-09
The drill needs no network: venv creation, sys.executable inspection, and ModuleNotFoundError reproduction all run offline.
对比候选资源与选型分析 (2)
Primary reference for pip commands, but the tutorial presents the create-activate-install loop as one beginner-friendly narrative.
Mature third-party environment tool with overlapping behavior; the stdlib venv tutorial was selected to avoid an extra dependency for first-time setup.
The Python Tutorial: Errors and Exceptions
对应章节 / 时间戳: Sections 8.3-8.6 (handling exceptions, else, finally, cleanup actions)
验证版本与日期: Python 3.12 (Verified: 2026-10-30)
Primary reference for try/except/else/finally semantics and the with statement as predefined cleanup for Day 11.
Basic Python syntax from Study Days 01-09
Every clause behavior in the lesson is demonstrated by runnable local snippets.
对比候选资源与选型分析 (2)
Solid lecture treatment but paced for a semester course and requires video viewing; the tutorial section matches the exercise scope directly.
Reference-style exception hierarchy listing rather than the tutorial narrative; retained as lookup material for the recovery drills.