你已经在 PyCharm 中运行过 Python 程序:点击运行按钮或按下快捷键,程序就会立即运行,结果显示在运行窗口中。窗口首行是一条完整的命令,程序正是由这条命令启动的。
本篇把 IDE 暂时放到一边,直接在终端中与 Python 解释器打交道:先学习即写即得的交互模式与以文件为载体的脚本模式,再学习以模块方式运行的命令写法。最后认识入门阶段最常见的三类报错,了解如何从报错信息中找到问题所在。学完本篇,你就能不依赖 IDE 运行自己编写的程序,也能在遇到报错时知道从何处入手。
1 交互模式
1.1 即写即得的执行环境
交互模式(Interactive Mode)是 Python 解释器提供的一种即时执行环境:输入一行代码,解释器立即执行并显示结果,随后等待新的输入;再输入、再执行,如此往复。
这种即写即得的反馈,让交互模式特别适合两类场景:一是验证写法,拿不准某条语句该怎么写,敲进去立刻看到效果;二是试验逻辑,用几行代码快速验证一个想法。学习 Python 的过程中,它会是你随手可用的 "草稿纸"。
1.2 进入、使用与退出
在终端中使用交互模式,完整的操作步骤如下:
- 启动终端: 按下 Windows 徽标键 + R 组合键,在弹出的 "运行" 对话框中输入 cmd 并回车,打开命令提示符窗口。
- 进入交互模式: 在终端中输入 python 并回车。终端会先显示当前 Python 的版本信息,随后出现 >>> 提示符。它由三个连续的大于号组成,表示解释器已经就绪,正在等待你输入代码。
- 执行代码: 在 >>> 之后输入 print("Hello, World!") 并回车,Hello, World! 随即出现在下一行;输出之后,>>> 再次出现,等待下一行输入。
- 退出交互模式: 输入 exit() 或 quit() 并回车即可退出;也可以按下 Ctrl + Z 组合键(终端会显示 ^Z)后再按回车。Ctrl + Z 在 Windows 命令行中代表文件结束符(end-of-file,简称 EOF),解释器读到该信号,便知道不会再有输入,随即退出。

退出交互模式后,提示符由 >>> 变回了目录提示符(图中为 C:\Users\Thanks>):前者表示你正在与 Python 解释器对话,输入的应当是 Python 代码;后者表示你正在与终端对话,输入的应当是 python 这样的命令。
2 脚本模式
2.1 脚本与脚本模式
在交互模式中输入的代码不会保存下来;要让程序能够反复修改与运行,更常见的做法是把代码写进文件。这种包含 Python 代码、可以交给解释器执行的 .py 文件,称为脚本(Script);把脚本交给解释器运行,这种运行方式称为脚本模式(Script Mode)。
脚本模式的执行过程并不复杂:解释器把脚本文件作为一个整体读入,再从头到尾依次执行其中的语句。与交互模式 "输入一行、执行一行" 的节奏不同,脚本模式交付的是一份完整的程序;代码保存在磁盘上,可以随时修改。此前在 PyCharm 中运行的 01_hello.py,正是一个脚本。接下来先不借助任何开发工具,手工创建一个脚本并在终端中运行它,把从创建到运行的每个环节看清楚。
2.2 准备脚本文件
这一节刻意不用 PyCharm,也不用现成的项目,而是用记事本和文件资源管理器手工创建脚本:创建脚本本质上只需要一个文本文件,并不依赖任何开发工具;亲手走一遍,你会对这一点有直观体会。演示脚本存放在 D:\Code_Space\Test\A\B,这个路径特意多设了几级目录,后文对比不同运行方式时,差异会更明显。整个创建过程只有四步:
- 新建目录: 打开文件资源管理器,进入 D:\Code_Space。在空白处点击右键,在 "新建" 子菜单中选择 "文件夹",命名为 Test;进入 Test,用同样的方式新建 A;进入 A,再新建 B。
- 新建文本文档: 进入 B 文件夹,同样在右键菜单的 "新建" 子菜单中选择 "文本文档",将文件命名为 hello_test------此时它的全名是 hello_test.txt。
- 写入代码: 双击 hello_test.txt,系统默认会用记事本打开它;输入这行代码 print("Hello, World!"),然后保存并关闭。
- 修改扩展名: 若扩展名没有显示出来,先按下方提示开启显示。随后把文件重命名为 hello_test.py(选中文件后按 F2,或右键选择 "重命名"),扩展名便由 .txt 改为 .py;若系统弹出确认更改的提示,点击 "是"。至此,hello_test.py 就是一个可以直接交给解释器运行的脚本。
💡 提示:显示文件扩展名
扩展名是文件名中最后一个点之后的部分,Windows 依据它识别文件的类型:.txt 代表文本文档,.py代表 Python 脚本。Windows 默认隐藏已知类型文件的扩展名------未开启显示时,hello_test.txt 在资源管理器中只显示为 hello_test,从文件名上分辨不出类型,也无从修改扩展名。开启显示的方法是:点击窗口顶部的 "查看" → "显示",勾选 "文件扩展名",操作路径如下图所示:
2.3 使用绝对路径运行
脚本就绪,先看第一种运行方式。它要用到**绝对路径(Absolute Path):**从盘符出发、完整描述文件位置的路径,例如 D:\Code_Space\Test\A\B\hello_test.py------无论终端此刻位于什么位置,这条路径指向的永远是同一个文件。操作步骤如下:
- 打开终端: 按下 Windows 徽标键 + R 组合键,输入 cmd 并回车。
- 运行脚本: 输入 python D:\Code_Space\Test\A\B\hello_test.py 并回车,Hello, World! 随即出现在终端中。

命令中的 python 并没有写明位置,系统却总能找到它,靠的是安装 Python 时写入环境变量 Path 的目录;但 Path 只负责帮系统找到 python 命令对应的程序,并不负责查找你的脚本文件。脚本的位置由命令中写出的路径决定:这条命令把脚本的绝对路径完整地交给了 python,解释器据此就能直接定位并运行脚本,不受终端所在位置的影响。
2.4 使用相对路径运行
用绝对路径运行脚本,每次都要在命令中写出一长串路径,比较繁琐。**相对路径(Relative Path)提供了另一种思路:**以终端当前所处的目录为基准来描述文件位置,这个作为基准的目录称为当前工作目录(Current Working Directory)。实际操作时,通常先把当前工作目录切换到脚本所在目录,再用文件名直接运行脚本。具体做法如下:
- 切换驱动器: 终端打开时默认位于 C 盘的用户目录,而脚本存放在 D 盘,因此先输入 D: 并回车,把当前驱动器切换到 D 盘;切换后目录提示符变为 D:>,表示当前位于 D 盘的根目录。
- 进入脚本所在目录: 输入 cd Code_Space\Test\A\B 并回车。cd 是 change directory 的缩写,作用是切换目录;命令执行后,目录提示符变为 D:\Code_Space\Test\A\B>。也可以用一条命令 cd /d D:\Code_Space\Test\A\B 达到同样效果:cd 默认只在当前驱动器内切换目录,加上 /d 参数后,它就能在切换目录的同时切换驱动器。
- 运行脚本: 输入 python hello_test.py 并回车。当前工作目录正是脚本所在的目录,解释器因此能够在这里找到 hello_test.py,随即执行,Hello, World! 出现在终端中。

与绝对路径方式相比,相对路径的命令短了很多,代价是多出两步切换操作。
💡 提示:区分系统命令与 Python 代码
上面几条命令的分工并不相同:D: 与 cd 是 Windows 命令提示符自带的命令,由终端本身执行,与 Python 无关;python命令则用于启动解释器,其后跟随的内容(例如脚本路径)才是交给 Python 处理的部分。也就是说,终端与解释器是两个不同的 "对话对象":在终端的目录提示符下,输入的是系统命令;进入交互模式、看到 >>> 之后,输入的才是 Python 代码。
2.5 从地址栏启动终端
写长路径、切换目录,这些操作其实都能省去:目录定位可以交给文件资源管理器完成。操作步骤如下:
- 定位目录: 打开文件资源管理器,进入脚本所在目录 D:\Code_Space\Test\A\B。
- 从地址栏打开终端: 点击窗口上方显示当前路径的地址栏,使其进入可编辑状态,输入 cmd 并回车。系统随即打开命令提示符窗口,并自动以该目录作为当前工作目录。
- 运行脚本: 输入 python hello_test.py 并回车,Hello, World! 出现在终端中。

这种方式无须手动输入长路径,也无须切换驱动器与目录,出错的可能性也更小。
现在,运行同一个脚本已经有了三种方式:绝对路径稳妥可靠,相对路径精简命令长度,地址栏方式则把目录切换交给资源管理器。三者效果相同,按场景与习惯选用即可。
💡 提示:PyCharm 运行程序的本质
此前在 PyCharm 中运行 01_hello.py 时,运行窗口在输出结果的上方显示过本次实际执行的命令:前半段是项目虚拟环境中解释器 python.exe 的完整路径,后半段是脚本 01_hello.py 的完整路径,如下图所示:
现在可以看清:这条命令正是 "以绝对路径运行脚本" 的形式。点击 "运行" 按钮、按下快捷键,或使用右键菜单运行程序,PyCharm 最终都会把操作转换成这样一条命令交给系统执行;真正运行程序的,始终是 Python 解释器------IDE 替你完成的,只是输入命令这一步。
3 以模块方式运行
3.1 认识模块
在前面的几种运行方式中,hello_test.py 都是作为脚本直接运行的。除此之外,Python 还支持以模块(Module)方式运行程序。要理解这种方式,先来认识模块这个概念。
模块的概念并不复杂:你编写的 Python 代码通常保存在 .py 文件中,而任何一个包含 Python 代码的 .py 文件,都是一个模块。模块的名称,就是去掉 .py 扩展名后的文件名------hello_test.py 对应的模块名就是 hello_test。于是,同一个文件有了两种称呼:直接运行时,它是脚本;以模块方式运行时,它是模块。
模块更深入的用法,例如在一个文件中使用另一个文件中的代码,后续文章再详细讲解;此处只需要记住 .py 文件与模块的对应关系。
3.2 使用 -m 参数运行
以模块方式运行,需要在 python 命令中使用 -m 参数。这类以 - 开头的参数写在命令之后,用于向解释器传达额外的指令。操作步骤如下:
- 打开终端: 在文件资源管理器中进入脚本所在目录 D:\Code_Space\Test\A\B,从地址栏打开命令提示符。
- 运行命令: 输入 python -m hello_test 并回车,Hello, World! 同样出现在终端中。

结合上一小节的模块概念,这条命令可以拆成三部分来理解:python 负责启动解释器;-m 告诉解释器,把它后面的名称当作模块来运行;末尾的 hello_test正是模块名------注意它不带 .py 扩展名,因为 -m 接收的是模块名而不是文件名。地址栏方式打开的终端已自动以脚本所在目录为当前工作目录,解释器按照模块的查找规则在这里找到 hello_test.py 并执行,运行效果与直接运行脚本相同。
3.3 随之出现的字节码缓存
以模块方式运行之后,打开脚本所在目录,会发现多出一个名为 pycache 的文件夹。

进入该文件夹,可以看到一个名为 hello_test.cpython-314.pyc 的文件。

这就是解释器生成的字节码缓存文件。此前介绍 Python 的执行机制时讲过,解释器在执行代码之前,会先把源代码编译为字节码------这个文件保存的正是编译结果,文件名中的 cpython-314 表示它由 CPython 3.14 生成,.pyc 则是这类缓存文件的扩展名。**缓存的作用是节省重复编译的开销:**只要源文件没有改动,下次以模块方式运行时,解释器直接读取缓存、跳过编译;源文件一旦改动,解释器会重新编译并更新缓存。此外,其他程序需要使用这个模块时,同样会受益于这份缓存,相关知识留待后续文章讲解。
直接运行脚本与以模块方式运行,还有一处关键差异:字节码是否写入磁盘。直接运行脚本时,字节码只存在于内存中,程序结束便随之释放,不会写入磁盘------这正是直接运行 hello_test.py,以及此前在 PyCharm 中运行 01_hello.py 时,都没有出现 pycache 文件夹的原因。以模块方式运行时,代码按照模块的加载流程处理,字节码会写入磁盘,形成缓存。
已经生成的 pycache 文件夹,删除也无妨------再次以模块方式运行时,它会自动重新生成。对单个小脚本而言,缓存带来的提速几乎察觉不到;当项目包含大量模块时,节省的编译开销才比较可观。
4 常见报错的识别与排查
在编程学习过程中,遇到报错是常态。报错信息是解释器给出的线索,读懂它,就能快速定位并解决问题。入门阶段常见的报错主要有三类:解释器没有找到要运行的文件;代码中使用了未定义的名称;代码中混入了非法字符。下面依次识别并排查这三类错误。
4.1 文件路径错误
在终端运行脚本时,若解释器找不到指定的文件,会给出如下报错:

图中上半部分是目录不对的情形------终端停在 C:\Users\Thanks,脚本却存放在 D 盘;下半部分是名字不对的情形------目录正确,文件名却多打了一个字母 t。
报错中的 can't open file 表示解释器打不开这个文件;随后单引号里的路径,是解释器实际尝试打开的完整位置------由此可以直接看出它到哪里查找过文件;末尾的 Errno 2 No such file or directory 是操作系统返回的错误编号与说明,含义是 "没有这样的文件或目录"。
报错里还有一个容易疑惑的细节:路径中的每个反斜杠,都显示为两个连续的 \\。实际的路径中只有一个反斜杠,这种成对的形式出自 Python 显示路径的方式,阅读报错时把它当作单个反斜杠看待即可;其原理后续文章再作说明。
图中两种情形的成因并不复杂:目录不对,是因为以相对写法给出的脚本路径,解释器只会在当前工作目录中寻找;名字不对,是因为输入的文件名与实际文件名不一致,哪怕只差一个字母,也找不到文件。
排查与修复的完整流程如下:
- 查看当前位置: 当前所在的目录已经显示在目录提示符中;也可以输入 cd 并回车,终端会单独打印一行当前工作目录。
- 切换目录: 若当前目录不是脚本所在目录,输入 cd /d D:\Code_Space\Test\A\B 并回车,切换过去。
- 确认文件存在: 输入 dir 并回车,列出当前目录下的全部文件与子文件夹,确认 hello_test.py 就在其中。
- 重新运行: 输入 python hello_test.py 并回车,Hello, World! 正常输出。

若目录正确、只是文件名输错,把命令中的文件名改正后重新运行即可。还有一个减少拼写失误的小技巧:输入文件名的前几个字母后按下 Tab键,终端会自动补全完整文件名,名字较长时尤其好用。
4.2 名称拼写错误
来看第二类错误。在 D:\Code_Space\Test 目录下新建 test_nameerror.py,故意把 print 误拼为 prnit:
python
prnit("Hello, World!")
运行 python test_nameerror.py,报错如下:

从下往上读这份报错,先看最后一行:NameError标明错误的类型;其后的说明指出,出错的名称是 prnit------程序中没有定义过这个名称,运行到这一行,程序随即中断。解释器还根据拼写相似度猜测你想输入的名称,附上一句修改建议:Did you mean: 'print'?
在 Python 中,这类在程序运行期间由解释器报告的问题统称为异常(Exception),NameError 便是其中一种------认出异常的名称,就等于知道了错误的类别。至于异常机制的详细讲解,留待后续文章。
上方的 Traceback(意为 "回溯")部分指明出错的位置:出错的文件路径、行号,以及用 ^ 标出的出错代码------图中五个 ^ 正落在 prnit 下方。今后遇到任何报错,都可以按照 "先看最后一行确定错误类型,再向上定位出错位置" 的思路来读。
把 prnit 改回正确的拼写,重新运行,程序即可正常输出。
4.3 标点符号混用
再看第三类错误。在 D:\Code_Space\Test 目录下新建 test_syntaxerror.py,把代码中的括号与引号写成中文全角符号:
python
print("Hello, World!")
运行 python test_syntaxerror.py,报错如下:

最后一行 SyntaxError: invalid character '(' (U+FF08) 指出代码中存在非法字符:单引号里正是那个字符------全角左括号;其后括号中的 U+FF08 则是该字符的 Unicode 编码(Unicode是一套为每个字符分配唯一编号的标准)。上方的 File 行给出了出错的文件与行号,代码下方的 ^ 则标出了非法字符所在的位置。
这类报错没有 Traceback 字样:SyntaxError属于语法错误,在程序运行前的语法检查阶段就被发现,程序根本没有运行。不过,"先看最后一行" 的阅读思路在这里同样适用。
错误的根源在于:Python 代码中的括号、引号、逗号、冒号等符号必须使用英文半角字符,而中文输入法默认打出的却是全角符号,二者外观极为相似,肉眼很难分辨。下表列出了入门阶段最容易混淆的几组符号:
| 符号类型 | 中文全角(错误写法) | 英文半角(正确写法) |
|---|---|---|
| 双引号 | " " | " " |
| 单引号 | ' ' | ' ' |
| 圆括号 | ( ) | ( ) |
| 逗号 | , | , |
| 冒号 | : | : |
处理这类错误时,根据报错给出的行号定位到出错代码,对照上表把非法字符改回英文半角即可。更有效的做法是从源头预防:编写代码时保持英文输入法状态,仅在需要输入中文内容时临时切换。另外,PyCharm 在这方面还有一道防线:非法字符通常在输入阶段就会被编辑器标红,无须等到运行才暴露。
📝 总结:运行方式与报错排查
本篇把运行 Python 程序的方式从 IDE 扩展到了命令行。交互模式即写即得,适合临时验证,但代码不留存;脚本模式以 .py 文件的形式保存代码,可以用绝对路径或相对路径运行,也可以从资源管理器的地址栏打开终端后运行。同一个文件还能以模块方式运行:python 命令加上 -m 与模块名即可,模块名就是去掉扩展名的文件名;这种方式会生成写入磁盘的字节码缓存,而直接运行脚本不会。报错排查方面,"先看最后一行、再向上定位" 是读懂报错的通用思路:文件路径与名称拼写错误,借助 cd、dir 与 Tab 补全即可快速排查;标点符号错误,对照全角与半角符号表即可化解。日常开发中,IDE 仍是主力工具,但经过本篇的练习,你对 "运行" 二字的理解会更加扎实:无论通过什么工具启动程序,真正执行代码的,始终是解释器。

