本章精髓 .py 文件双击没有反应,不是文件坏了,是这台机器上还没有能执行它的程序。网页能双击打开,是因为系统预装了浏览器;安装 Python 的实质,就是给 .py 文件配一个执行者。
学完本章后,你应该能够:
- 说清一个 Python 程序跑起来经过哪三个环节,其中哪一环需要自己动手装;
- 在 Windows 上装好解释器,并用两条命令验证它确实装成了;
- 用终端切换当前目录,以命令方式运行指定的 .py 文件;
- 照四个前提条件逐条排查运行失败,而不是反复重装;
- 读一段栈回溯,说出错误类型与出错行号,并按四件套向大模型求助。
成品 · 三个环节 · 报错原样贴回去
这一部分的难点不在代码,在于让它跑起来。
1.1本章成品:随机点名器
成品是一个只有十几行的 Python 程序。名单写在代码里,运行后从中随机取出一个姓名,显示在终端上。要增减名单,改代码里的那一行,保存后重新运行。
提示符前面的那段路径,就是终端此刻所处的目录
代码由大模型生成,几分钟就能拿到。本章要花时间的,是让它在你面前这台机器上真的跑出结果。前八章的作品双击就能打开,这一章的作品双击没有任何反应,差别就是这一部分要讲清楚的东西。
1.2从文件到结果,中间要经过谁
运行一个 Python 程序,实际发生的是三个环节:
三个环节里,只有中间那一环需要自己装
网页文件之所以双击就能打开,是因为承担中间一环的浏览器由系统预装。解释器不在预装名单里。
两类文件都是纯文本,差别在于系统里有没有对应的执行程序
这也是前八章一直没提的一件事:你做的网页能在别人机器上打开,靠的是别人机器上也有浏览器。凡是要靠某个程序才能跑起来的东西,交付时就得考虑对方那边有没有这个程序。
1.3本章新技巧:报错原样贴回去,给证据不给结论
向大模型描述故障时,要给的是四项内容:我做的操作、我预期的结果、实际发生的现象、报错信息的完整原文。前三项交代现场,第四项是判断依据。
报错信息里看起来最像废话的那几段,恰恰是定位价值最高的:文件的完整路径说明它读的是哪个文件,行号说明断在第几行,字符编号说明是这一行的第几个字符。转述一遍,这些全丢了。
1.4可直接复制的提示词
第二段提示词里的四条要求,每一条都对应后面要讲的一个知识点:
1.5大模型的常见偏差
只返回改好的代码,不作解释。 这样能解决当次问题,同类错误再出现时你仍然判断不了。"请先用中文解释这段报错的含义"这句要保留,而且要放在"再说明应当改哪一行"前面。
忽略你贴的报错,重写整份脚本。 重写之后的代码和你手上那份不再对应,改了哪里无从核对。必须写明不要重写整个脚本,只给出需要修改的那几行。
附送你没要的功能。 最常见的是加图形界面、语音播报、表格导出。这些都依赖第三方库,在机房网络下装起来很慢。"只用标准库""不要做图形界面"两句要同时写上。
第09章演示_四条件模拟器.html 与 第09章演示_报错拆解.html 是网页,双击就能开,不需要装任何东西,也不需要联网,可以先用它们把四个条件和报错读法过一遍。
解释器 · PATH · 终端 · 当前工作目录 · 扩展名
本章的核心内容集中在这一部分和第四部分。
这八个术语会原样出现在安装界面、报错信息和技术文档里。前五个在本部分讲解,第六、七个在第三部分,第八个在第四部分。
2.1五个知识点,一个一个看
装 Python,装的主要就是这一个程序
现象:双击 点名.py 之后没有窗口出现,或者弹出一个"选择打开方式"的对话框。
概念:.py 文件是纯文本,里面的语句要由一个专门的程序读取并执行,这个程序叫解释器(interpreter)。浏览器由系统预装,所以 .html 双击就能开;解释器不属于预装组件,装它之前,系统不知道该拿这个文件怎么办。
类比:乐谱本身不会发出声音,要有演奏者按谱演奏。
没登记进这份清单,就会全部未找到
现象:安装界面第一屏下方有一个复选框。没勾的人在终端里输入 python,会得到"不是内部或外部命令"。
概念:PATH 是一项环境变量,内容是一组目录路径。在终端里输入命令名之后,系统按顺序到这些目录里找同名的可执行文件,全部找不到就报告命令不存在。勾上那个复选框,就是把 Python 的安装目录写进这组路径。
类比:门卫处登记的住户名单。人确实住在楼里,没登记就是查无此人。
版本号因安装版本而异,能显示出来就算装成了
现象:一个只显示文字的窗口,行首是一段路径,后面跟着等待输入的光标。
概念:终端(terminal,也叫命令行界面 command line interface)是操作系统提供的另一种交互方式:输入命令下达指令,而不是点击图标。Windows 上常用的是命令提示符与 PowerShell。程序的输出和报错都显示在这个窗口里,所以本章的操作都在终端内完成。
类比:在餐厅可以指着菜单点,也可以直接报菜名。后者更快,前提是你知道菜名。
两者不在同一个位置,要先用 cd 切过去
现象:文件明明在桌面上,终端却提示 can't open file。
概念:终端在任何时刻都处在某个目录之下,这个目录叫当前工作目录(working directory),提示符前面那段路径就是它。命令里给出的文件名,默认是相对于这个目录去找的。切换目录用 cd 命令,即 change directory。
类比:在校园里说"三楼那间教室",对方得先知道是哪一栋楼。
解释器能执行
只是一个文本文件
资源管理器默认隐藏扩展名,两者在文件夹里显示成同一个名字
现象:用记事本保存之后,终端提示找不到这个文件。
概念:Python 源文件是纯文本文件,扩展名必须是 .py。记事本默认按 .txt 保存,"保存类型"没改成"所有文件",得到的就是一个文本文件。资源管理器默认隐藏已知扩展名,要在"查看"里打开显示扩展名,才看得到文件名真实的结尾。
类比:扩展名相当于包裹上的品名标签。标签写错,分拣时就会送到别处。
2.2四个前提条件
上面五个知识点,在实际操作里合成四个必须同时成立的条件。少任何一条,程序都跑不起来,而且四种情况给出的提示各不相同。
打开 第09章演示_四条件模拟器.html,把四个开关任意关掉几个,看终端会给出哪一句提示。反过来练更有用:先看提示,再判断是哪一条没成立。
2.3本章要用的四条命令
标准输出 · 库与 pip · 逐行核对
不用逐字读懂,但要知道改哪一行、为什么有这一行。
3.1另外两个知识点
算过不等于显示过
现象:终端里出现的那几行文字。
概念:print 把括号里的内容送到终端上显示,这条输出通道叫标准输出(standard output)。程序内部的计算过程不会自动显示,没有经过 print 的结果不会出现在屏幕上。运行之后"什么反应都没有",常见原因之一就是代码里根本没有输出语句。
类比:心算完了不报答案,旁人无从知道你算没算过。
两层库的区别只有一个:需不需要先装
现象:代码第一行的 import random;有些代码还要求你先在终端里执行一句 pip install。
概念:库(library)是别人写好、可以直接使用的一批功能。随 Python 一同安装的那批叫标准库,random 就是其中之一。标准库以外的叫第三方库,要用 pip 从网上装到本机。无论哪一种,使用前都要用 import 这一句取出来,没有 import 而直接使用,解释器会报告名称未定义。
类比:工具箱里备着工具,用之前还是得先伸手取出来。
3.2本章的完整代码
下面这份代码由大模型生成,共十六行,其中五行是注释。名单写在第二段的方括号里,增减姓名只改这一行。
# ① 导入标准库 random,它提供随机选择功能
import random
# ② 名单直接写在代码里。增加或删除姓名时,改这一行即可
names = ['林晓', '周敏', '赵鹏', '陈立', '孙倩', '王一凡', '李文博', '黄雅琴']
# ③ 从名单里随机取出一个元素
picked = random.choice(names)
# ④ 把结果输出到终端
print('名单共', len(names), '人')
print('本次抽中:', picked)
# ⑤ 双击运行时窗口会在程序结束后立刻关掉。这一行让程序停在这里等一下
input('按回车键结束')
按本章方法核对一遍:输入是 ② 的名单,输出是 ④ 的两条 print,这一份里没有重复执行的部分。
3.3把名单从代码里搬出来
上面那份代码有一个明显的限制:换一个班就要改代码。让名单住到一个单独的文本文件里,改名单就不必碰代码了。
# ① 导入标准库 random
import random
# ② 从同一个文件夹里的 第09章演示_名单.txt 读名单,一行一个姓名
with open('第09章演示_名单.txt', encoding='utf-8') as f:
names = [line.strip() for line in f if line.strip()]
# ③ 名单为空时直接说明,不要装作抽了一次
if len(names) == 0:
print('名单文件是空的,请先往里面写几行姓名')
else:
print('名单共', len(names), '人')
print('本次抽中:', random.choice(names))
input('按回车键结束')
这一版多出两件事,都值得留意。encoding='utf-8' 是在告诉解释器按哪一套编码去读这个文件,不写这一句,中文姓名在部分机器上会读成乱码。第 ③ 段处理的是名单文件存在但里面一个字都没有的情况,这一步不做,程序会在你看不见的地方出错。
第09章演示_名单.txt 和 .py 文件在同一个文件夹里,并且终端的当前目录也在这里。把 .py 单独发给同学而不带名单文件,对方运行时会得到 FileNotFoundError。这正是第八章说的交付物不完整,只是换成了 Python 的形态。栈回溯 · 从最后一行读起 · 五类高频报错
程序中断时给出的那几行英文,是这门课里信息密度最高的东西。
4.1第八个知识点
最后一行给类型,上面几行给位置
现象:程序中断后,终端里出现的若干行提示,通常以 Traceback 开头。
概念:这段信息叫栈回溯(traceback),是解释器在执行中断时输出的诊断记录。最后一行给出错误类型与具体原因,上面各行给出出错的文件、行号和那一行的源代码。所以阅读顺序应当从最后一行开始,再往上找位置。
类比:查快递先看最新一条,它才说明包裹现在在哪。
4.2四行报错,逐行拆开
下面这段是运行 第09章演示_报错1_库名拼错.py 之后终端的实际输出,一个字没改。
打开 第09章演示_报错拆解.html,五类报错各拆一遍。页面会按 ④②③ 的顺序把三行依次点亮,这就是你以后读报错时眼睛该走的路线。
4.3五类高频报错速查
本章实践里出现频率最高的五类如下。先按最后一行确定类型,再依据第二行定位到具体的行。
三个报错演示文件分别对应表中的第一、三、四类,各运行一次就能看到真实输出。
4.4报 bug 三件套
你在互测里发现同组同学的程序有问题,或者要向教师描述一个故障,交出去的东西应当有三样:
终端窗口的完整截图,看得到提示符路径、输入的命令和全部输出。只截输出那一段,看不出他是在哪个目录下运行的。
从解压开始,一步一步写到出问题的那一步,写到对方照着做能得到同样的结果为止。
你原本以为会看到什么。少了这一条,对方只知道你不满意,不知道你要的是什么。
4.5前沿三分钟:报错信息的可读性
每章固定栏目 · 一条与本章内容相关的行业动态
早期的编程语言出错时往往只给一句 syntax error,具体位置和原因要使用者自己排查。近年这一状况有明显改变。Python 的报错先是加入了拼写推测,名称写错时会提示 Did you mean;此后在报错里加入了指向具体表达式的标记符号;再往后,漏掉 import 语句也会被一并指出。
这一变化的出发点是:读报错属于日常工作里的高频动作,报错说得清楚,节省的是全部使用者的时间。已经有语言项目把报错信息的可读性写进主要特性对外说明,也就是把它当产品的一部分来设计,而不是当日志。
对本章的实际影响有两点:安装时不必特意去找旧版本,新版本的报错给的线索更多;但这些信息仍然是英文,仍然要读到最后一行才能确定类型。
三选一 · 六步 · 报错记录四项
上机环节由此开始,当堂完成并提交。
5.1三个题目,任选其一
名单写在代码里,随机抽一人,同时显示名单人数。
通用书单写在代码里,随机推荐一本,可以附上作者姓名。
偏文科名单写在代码里,打乱后按每组指定人数划分,逐组输出。
偏理工三个题目的数据都写在代码里,运行方式与验收标准一致。允许更换题材。
5.2上机六步
5.3共同验收标准
5.4常见错误与处理
py 点名.pycd 切过去input('按回车键结束'),或者改在终端里运行dir 确认两个文件都在当前目录下,再运行5.5提交内容
提交方式:按教师提供的作业模板填写,文档开头注明所选题目。提交渠道见课堂通知,当堂提交。
5.6再进一步(选做)
让抽取结果不重复:在代码里另设一份已抽名单,每次抽中之后把这个姓名移出候选范围。
做完会碰到一个需要判断的情形:候选范围只剩一个人时,这一次抽取的结果是确定的。此时程序应当照常输出,还是给一句提示并重新开始,由你自己决定,并把决定写进说明。
更进一步的一版是把名单搬进 第09章演示_名单.txt,让改名单不必碰代码。做到这一步,你交出去的就不再是一个文件,而是一个包。
本章五条结论
- .py 双击没反应,是因为系统里缺一个能执行它的程序。装 Python 就是给它配这个执行者。
- 程序能跑起来要同时满足四个条件:解释器已装、路径已登记、文件是 .py、终端在文件所在目录。上机时的多数问题都能归进其中一条,按顺序核对比重装一遍有效。
- 栈回溯从最后一行读起。最后一行给类型,上面几行给文件与行号。
- 向大模型求助时交四项:操作、预期、现象、报错原文。转述一遍,定位所需的信息就丢了。
- 报错会停下来,不报错但结果不对不会。人数那一行不影响抽取结果,作用是让这类问题露出来。