📖 名词溯源:Python 和「蟒蛇」没关系 Python 这个名字不是来自蟒蛇,而是来自英国喜剧团体 Monty Python。它的创始人 Guido van Rossum 是这部剧的粉丝,1989 年圣诞节期间想做一个「好读、好用」的语言,就顺手借用了这个名字。所以 Python 的吉祥物虽然画成两条蛇,但名字的本意是「有趣、好玩」。
🎯 本章学习目标
- 理解为什么 Python 适合零基础入门,以及它和别的语言的关系。
- 彻底搞懂「编译」和「解释」两种翻译方式的区别,以及「解释器」是什么。
- 知道如何安装 Python 解释器,并验证安装成功。
- 写出并逐行理解你的第一个程序,搞清它从代码到输出的完整旅程。
- 会用 REPL 做「计算器式」即时验算,并说清 REPL 与脚本文件的分工。
- 遇到「命令找不到」类安装问题,能按排查思路定位并解决。
3.1为什么推荐 Python
世界上有几百种编程语言,各有各的用武之地。作为零基础成人自学,我们推荐 Python,理由很实在:
| 理由 | 说明 |
|---|---|
| 语法接近人话 | 代码读起来像英文句子,几乎不用背花括号、分号等「仪式感」符号。 |
| 少写样板代码 | 干同样的事,Python 往往比别的语言少写一大半代码。 |
| 用途极广 | 网站、数据分析、人工智能、自动化脚本……一个语言通吃多个方向。 |
| 生态庞大 | 有海量现成的「库」可调用,很多功能别人已经帮你写好了。 |
但请你记住一个关键观念:学的是「编程的思维」,不是「Python 的语法」。变量、循环、函数这些概念,几乎在所有语言里都存在,只是写法略有不同。用 Python 入门,是为了让你把精力花在「理解原理」上,而不是跟语法符号较劲。
为什么「语法接近人话」对入门如此重要
这背后有个朴素的心理事实:人的工作记忆容量有限,一次只能同时握住几个信息块。学编程时,你真正要装进去的是「变量、循环、函数」这些概念;如果语言还要求你同时记住「每行结尾要写分号、代码块要用花括号包住、变量必须先声明类型」这些仪式,工作记忆就被仪式挤占了——概念反而学不进去。仪式感重的语言自有它的道理(后面辨析里会替它们说句公道话),但对零基础的学习者,仪式是纯负担。
Python 的选择是把这些仪式几乎全部删掉:没有分号、没有花括号、很多场合连类型都不用声明。你在第 1 章写的伪代码「合格数 = 合格数 + 1」,到 Python 里原样能跑(ok = ok + 1)。语言贴近你的思考,而不是让你贴近语言——这是「适合入门」的全部秘密。同时它还附带一个工程红利:代码即文档,几个月后回读自己脚本时,贴近人话的代码几乎不用注释也能读懂。
「少仪式」还直接关系到自学能不能坚持下来。零基础学编程的流失高峰,恰恰在最初两周——不是内容有多难,而是挫败感来得太快:满屏报错、程序跑不起来、不知道错哪了。此时语言每多一分仪式,就多一个「卡住你」的机会:漏个分号报错、花括号不配对报错、类型没声明报错……而 Python 把这些「非智力性障碍」降到最低,让你把有限的耐心花在真正值得的地方——理解变量、循环、函数这些会陪伴你整个编程生涯的概念。学习工具的意义,就是把挫折留给该有的难,而不是语法题。
核心思想 语言是工具,编程思维才是真正要学的东西。Python 只是这套思维最省力的「练习工具」——它语法最简单,让你能专心打地基,而不是先爬过一堆语法障碍。
📐 例题 1 同一任务:Python 要写几行?
任务:把 1、2、3、4、5 这五个数的平方,逐行打印出来。请用 Python 完成,运行验证输出;并对照估算:换一门语法仪式感较重的常见语言(先声明类与主函数、语句以分号收尾、代码块加花括号),完成同一任务大约要写多少行?
思路 「打印 1 到 5 的平方」= 循环(从 1 数到 5)+ 每轮算平方并打印。用第 1 章的伪代码先搭骨架:「对 i 从 1 到 5:打印 i×i」,再逐字翻译成 Python。
解 伪代码直译:
for i in range(1, 6): # 对 i 从 1 数到 5(不含 6)
print(i * i) # 每轮打印 i 的平方
运行输出:
1
4
9
16
25
两行完成任务。对照常见仪式感较重的语言,同样的事通常要先声明「类」与「主函数」的骨架,再在骨架里写循环,语句逐条以分号收尾、代码块用花括号包住——不算空行通常要五到八行。行数差距就是仪式感的直观度量;注意这只是入门阶段的观察角度,仪式感的工程价值见下面辨析。
答:Python 两行,输出 1、4、9、16、25;仪式感较重的常见语言约五到八行。 ⚠ 易错点:range(1, 6) 是「从 1 到 6 不含 6」——这是新手第一大坑,想要 1~5 就写 range(1, 6);若写成 range(1, 5) 只会打出 1、4、9、16,少一项。
放到工程现场看,这套特性恰好命中工程人员的日常需求:整理一批试验数据、批量重命名上百个文件、从传感器日志里筛异常值——这类任务用 Python 往往十几行、半小时就能交付一个能跑的小工具,而开发同样的工具用仪式感重的语言可能要多花数倍时间。对以「解决本岗位问题」为目标的工程学习者,上手快、生态全、立刻有用,比什么都重要。
再把镜头拉远一点,看看 Python 在整个语言谱系里的位置。从第 2 章你已经知道,「离机器近」和「离人近」是两端:机器码与汇编贴着硬件,写起来痛苦但控制力最强;Python 站在「离人近」的一端,把硬件细节全部藏起;C、C++、Java、Go 等则散布在中间地带,各有各的取舍。谱系没有高下,只有位置不同——就像民航客机与直升机不是谁更先进,而是任务剖面不同。入门从「离人近」的一端起步,先建立编程思维的全景;将来如果岗位需要贴硬件的功力(比如嵌入式、实时仿真),再沿着谱系向机器那端走,此时你会发现循环、条件、函数这些概念原封不动,变的只是「仪式」的多少。
辨析环节,替「仪式感重」的语言说句公道话:显式的类型声明、严格的语句结构并非繁文缛节——类型声明让编译器在运行前就拦下一大类错误,严格结构让大型工程的多人协作有章可循。大型机载软件、实时控制系统偏爱这类「啰嗦但严谨」的语言,看中的正是「编译期把问题揪出来」的能力。所以请建立平衡的认知:仪式有仪式的岗位,简洁有简洁的岗位;入门选简洁是为了快速建立思维,思维立住之后,第二门语言随岗位需要再学,成本会低得多——因为概念是通用的,变的只是写法。
3.2编译 vs 解释:代码怎么变成机器码
上一章说过,高级语言写的源代码最终要翻译成机器码才能运行。翻译这件事,有两种截然不同的做法:编译(compilation)和 解释(interpretation)。
编译:先整本翻译,再交给机器
编译型语言(如 C、C++、Rust)的工作方式是:写完全部代码后,用一个叫 编译器(compiler)的程序,把整份源代码一次性翻译成机器码,生成一个可执行文件。以后每次运行,直接跑这个机器码文件,翻译只需做一次。
解释:一句一句翻译,翻一句执行一句
解释型语言(如 Python)的工作方式是:一个叫 解释器(interpreter)的程序,读一行、翻译一行、执行一行,边读边做。没有「整份提前翻译」这一步。
两种方式带来的工程差异,比「快慢」二字丰富得多。编译型的产物是独立的可执行文件:交付给用户后,对方机器上既不需要源代码、也不需要编译器,装上就能跑——但代价是每次改动哪怕一行,都要重新走一遍完整编译。解释型的源代码永远需要解释器在场:把 .py 文件拷给同事,对方机器上必须装有 Python 才能运行;好处是改完即跑,翻译成本被摊薄到几乎为零。这个差异直接决定了两类语言各自适合的交付形态,下一道例题会把这笔账算成数字。
先把两个隐含量级说透,再看数字。「2 秒编译」在真实项目里可不是常数:一个几万行的大项目,完整编译动辄几分钟到几十分钟,正因为贵,大团队才发明了「增量编译」——只重编改动过的部分。而「每次 0.5 秒」也不只是慢:解释执行意味着运行期还要现场翻译,同样的算法,解释型语言的总耗时通常比编译型高一个量级。所以真实的取舍是「开发节奏」与「运行极限」的交换:要改得快,就接受跑得慢一点;要跑得极致,就接受编译等待。数据脚本几乎永远选前者,机载实时控制几乎永远选后者。
两种翻译时机还带来一个初学阶段就能感知的差异:错误被发现的时机不同。编译型语言在「整体翻译」时就把全文件的语法问题兜底查一遍——还没运行,一大类错误就被编译器点名批评;解释型语言是「执行到哪行才翻到哪行」,一个埋在第 200 行的笔误,只要程序前 199 行还没跑完,它就安静地躺着。这呼应第 1 章讲过的三类错误:语法错误编译器能拦、解释器要跑到了才报;而逻辑错误,无论哪种语言、哪种时机,机器都永远发现不了——只能靠人。第 6 章会专门展开「调试」这门手艺。
📐 例题 2 编译与解释的总耗时账:跑几次能回本?
某程序有两种交付形态。编译型:第一次使用前花 2 秒整体编译,之后每次运行 0.01 秒;解释型:直接运行,每次 0.5 秒。问:(1) 分别运行 1 次、5 次、10 次、100 次时,两种形态各自的总耗时是多少?(2) 从第几次运行开始,编译型的总耗时反超解释型、变得更划算?(3) 由此说明:什么样的项目该选哪种形态?
思路 列两条总耗时公式再对表:编译型总耗时 = 2 + 0.01n;解释型总耗时 = 0.5n(n 为运行次数)。令两式相等解出临界 n,再代入几个点核验——全部用程序算。
解 逐点计算:n=1 时编译型 2.01 秒、解释型 0.5 秒;n=5 时 2.05 对 2.5 秒;n=10 时 2.10 对 5.0 秒;n=100 时 3.00 对 50.0 秒。临界点:2 + 0.01n = 0.5n 解得 n = 2 ÷ 0.49 ≈ 4.08,即从第 5 次运行起,编译型全面占优。验算:
for n in (1, 5, 10, 100):
print(n, round(2 + 0.01 * n, 3), 0.5 * n) # 次数, 编译型总秒, 解释型总秒
print(2 / 0.49) # 4.08... 临界运行次数
运行输出:1→2.01/0.5;5→2.05/2.5;10→2.1/5.0;100→3.0/50.0;临界 4.08——与手算一致。第 100 次时两者差出 47 秒,运行次数越多、差距越悬殊。
答:(1) 见上表;(2) 临界约 4.08 次,第 5 次起编译型占优;(3) 频繁修改、跑一两次就要交活的(试验脚本、数据整理)适合解释型;一旦写好、长期反复运行的(设备固化软件、批量作业程序)适合编译型。 ⚠ 易错点:别把「解释型慢」绝对化——单次 0.5 秒对人是无感的;也别忘了编译型每改一行都要重付 2 秒编译,开发期这笔账要反复付。真正的判断标准是「改动频率 × 运行次数」。
把这道题的结论放进工程语境:地面试验的数据处理脚本,一天改二十遍、每版跑一次,解释型语言让工程师的节奏不被「等编译」打断;而装机交付的成品控制软件,固化后要在设备上连续运行几年——编译一次、终身全速,编译型的账算得漂亮。「选语言」的第一问从来不是「哪个好」,而是「这个东西改得勤不勤、跑得久不久」。
辨析一个进阶事实:编译与解释的边界并不是非黑即白。现代 Python 其实内部有「字节码」中间层——解释器先把源码快速编译成一种中间形态(字节码文件),再由内置的虚拟机逐条执行;Java、C# 更是「半编译半解释」的典型。所以严谨的说法是:两种「翻译时机策略」构成一个光谱,多数语言各取所需。入门阶段你只需抓住本质模型——先翻后跑 vs 边翻边跑——其余细节等你真正需要时自然会回来补。
翻译时机之外,选语言还有第二把尺子:动态类型 vs 静态类型。C、Java 这类静态类型语言要求写代码时就声明每个变量的类型(如 int x;),翻译阶段就逐行核对「类型对不对」,错误在程序跑起来之前就被拦住;Python 这类动态类型语言不写声明,变量的类型是运行到那一刻「实际装了什么」就是什么——写起来轻快、改起来灵活,但类型错误会藏到运行时才爆出来。取舍很务实:改得勤、试得快的探索型工作,动态类型省事;几十万行、要跑十年的大系统,静态类型把错误提前到上线之前。有趣的是两个世界正在互相取经:Python 3.5 起支持「类型注解」——下面代码里冒号后的 int 和箭头后的 int 就是,给动态语言补上人和工具都能检查的类型提示,却不改变运行方式。第 5 章会正面讲类型系统,到时候值得回来重读这一段。
def double(x: int) -> int: # 冒号后是「类型注解」:提示但不强制
return x * 2
print(double(21)) # 42:注解帮人和工具看懂代码,不改变运行方式
核心思想 无论编译还是解释,本质都是「人话 → 机器话」的翻译,只是「什么时候翻、翻多少」不同:编译先翻后跑,解释边翻边跑。Python 依赖的那个「边翻边跑」的程序,就是我们要安装的解释器。
3.3安装 Python 解释器
要跑 Python 代码,电脑上必须装一个 Python 解释器。安装很简单,分三步:
- 打开 Python 官网 python.org,进入 Downloads(下载)页面。
- 下载适合你系统的安装包(Windows 用户下载 Windows installer,Mac 用户下载 macOS installer)。
- 运行安装程序。注意:Windows 上务必勾选「Add Python to PATH」(把 Python 加入系统路径)这一项,否则后面在命令行里会找不到 Python。
分系统看一眼:三种平台各自的路
Windows:官网下载 installer,双击运行。安装界面第一屏的最下方就有「Add Python to PATH」复选框——默认不勾,请务必亲手勾上。想更稳妥,可点「Customize installation」自定义安装,确认勾选 pip(包管理器)与 py launcher(Python 启动器)等组件,再一路下一步。装完后在命令行验证(见下)。
macOS:官网提供 pkg 安装包,双击安装即可;会用终端的开发者也可以选择包管理器(如 Homebrew),在终端执行 brew install python 后由其统一管理升级。要留意一点:部分 macOS 自带一个仅供系统使用的旧版本,直接敲 python 可能唤起它——用 python3 这个名字调用新装的版本更保险。
Linux:多数发行版出厂已预装 Python(系统组件依赖它),但未必是你要的版本。终端里用包管理器即可安装或升级,例如 Debian/Ubuntu 系执行 sudo apt install python3,Fedora 系执行 sudo dnf install python3。Linux 上命令名几乎总是 python3 而不是 python——历史上后者曾被留给 Python 2。
装完后,要验证一下是否成功。打开「命令行」或「终端」(Windows 上可按 Win + R 输入 cmd 回车),输入:
python --version
如果屏幕上出现类似 Python 3.12.x 的字样,说明解释器装好了。这个命令的意思就是「问解释器:你是什么版本?」(macOS 与 Linux 用户如遇不识别,请改试 python3 --version。)
要点 python 是一个命令,它会启动你刚装好的解释器。--version 是告诉它「先别干活,报一下版本号」。以后你写代码、跑代码,都要通过这个解释器来完成。
PATH:为什么漏勾一个复选框,命令行就「找不到 Python」
那个加粗提醒的「Add Python to PATH」到底勾的是什么?要理解它,先认识 PATH(系统路径):它是操作系统维护的一张「目录清单」——你在命令行敲下 python 时,系统不会满盘乱找,而是按这张清单的顺序,逐个目录翻找有没有一个叫 python(或 python.exe)的可执行文件:找到就启动,清单翻完还没有,就报「不是内部或外部命令」。安装程序勾选「Add Python to PATH」,本质就是把 Python 安装目录登记进这张清单。漏勾的后果很好预见:Python 明明装了,清单里却没有它——系统自然「找不到」。
补救办法有两条路:一是重跑一遍安装程序,在「Modify(修改)」模式下补勾 PATH 那一项,最省心;二是手动把安装目录(形如 C:\Users\你的用户名\AppData\Local\Programs\Python\Python312)追加进系统环境变量的 Path 里。理解了 PATH 的机制,你还能顺手理解一类工程常见问题:「工具明明装了、命令行就是找不到」,八成是同一张清单出了岔子——排查思路完全一样。
📐 例题 3 安装排错:三种典型「翻车现场」逐个诊断
新学员装完 Python,在命令行敲 python --version,可能撞上三种典型情形。请给每种情形定位原因并给出解决步骤:
情形 A:提示「'python' 不是内部或外部命令,也不是可运行的程序」。情形 B:敲 python 没反应或弹出了应用商店,但敲 py --version 却能出版本号。情形 C:敲 python --version 显示的是 Python 2.7.18。
思路 三种情形对应三个不同的病根:A 是查找机制问题(PATH 里没有);B 是名字映射问题(Windows 的启动器叫 py);C 是版本指向问题(PATH 里排在前面的旧版本抢了先)。按「系统怎么找命令 → 找到了谁」两步排查。
解 情形 A:Python 安装目录不在 PATH 里。解决:重跑安装程序补勾「Add Python to PATH」,或手动把安装目录加入环境变量;改完重开一个新的命令行窗口再试(旧窗口读的还是旧清单)。情形 B:Windows 提供的 Python 启动器名为 py,装好后系统里还有个别名把 python 指向了应用商店占位符。解决:直接用 py 或 py -3 启动即可;也可在「管理应用执行别名」设置里关掉商店占位符。情形 C:PATH 清单里 Python 2 的目录排在更前,抢先匹配。解决:调整 PATH 中目录的先后顺序,把新版本目录提到最前;macOS/Linux 上则改用 python3 --version 调用新版本。
顺带一个通用心法:命令行工具排错,永远先问两个问题——「系统在哪里找这个命令?」「它找到的到底是谁?」九成的「装了却用不了」都栽在这两问里。
答:A→补 PATH 并重开终端;B→改用 py 启动器(或关闭商店占位别名);C→调 PATH 顺序(或改用 python3)。 ⚠ 易错点:改完环境变量必须重开命令行窗口——已打开的窗口不会自动刷新清单,这是「明明改了却还报错」的头号原因。
顺带解开一个 Windows 特有的疑惑:装完 Python,命令行里有时能用的不止一个名字——python 和 py。py 是安装包附带的「启动器」,它像一个总调度:查一遍系统里装了哪些 Python 版本,默认挑最新的给你,也可以用 py -3.8 这样的写法点名某个版本。而 python 这个名字则完全交给 PATH 清单决定,指向谁就是谁。所以「py 能用、python 不能用」在 Windows 上非常常见——不是装坏了,是两个名字走的是两条查找路径。搞清这点,你能少走很多弯路。
📖 什么是「命令行 / 终端」? 很多人被「命令行」吓到,其实它就是一个纯文字的操作窗口——你用键盘敲命令,计算机用文字回答你。它没有鼠标、没有图标,但它是和计算机打交道最直接、最「贴身」的方式。程序员天天用,你很快就会习惯。
再补一个工程视角:正式的工程交付讲究环境一致性——同一份脚本,在你机器上跑得好好的,换台机器报错,多半是两边 Python 版本或依赖库不同。所以从今天起养成一个习惯:给别人脚本时,顺带注明「用什么版本跑过」;接手别人的脚本时,先查 python --version。这个习惯将来对接正式的数据交付与追溯时,价值巨大。
再往前预告半步:当你的项目越攒越多,会发现不同项目想要不同版本的 Python 或不同版本的库——它们挤在同一台机器上难免打架。业界的解法叫「虚拟环境」:给每个项目单独圈一块互不干扰的运行环境。这个概念现在不用动手,知道「有这么个东西、它解决什么问题」即可;等第 11、12 章项目实战需要时,我们会正式把它请出来。工具总是在问题出现时学最快,提前死记反而记不住。
辨析一组容易张冠李戴的东西:解释器、编辑器、IDE。解释器负责「翻译并执行」你的代码,是今天的主角;编辑器(记事本、Notepad++、VS Code 等)只负责「把代码写出来、存成文件」,自己不运行任何代码;IDE(集成开发环境)则是「编辑器 + 调试器 + 各种辅助工具」的套装。初学阶段不需要 IDE:一个解释器加任意文本编辑器就能完成本课程全部练习——少一层工具,就少一层与学习无关的干扰。等你写到几十行的多文件项目时,再自然过渡到 IDE。
3.4你的第一个程序:Hello, World!
几乎所有编程教程的第一个程序,都是让计算机打印一句 Hello, World!。这已经成了程序员的「成人礼」。我们来写它,并逐字理解。
先新建一个文本文件,命名为 hello.py(.py 是 Python 代码文件的扩展名),在文件里写入这一行:
print("Hello, World!")
然后在命令行里,切换到文件所在目录,运行:
python hello.py
屏幕上会显示:
Hello, World!
这一行代码,逐字拆解
别看只有一行,它里面藏着好几个关键概念,我们一个个看:
| 片段 | 它是什么 | 作用 |
|---|---|---|
print | 一个函数(内建功能) | 「把东西显示到屏幕上」这个动作的名字 |
( ) | 函数调用的括号 | 告诉 Python「现在要执行 print 这个动作」 |
"Hello, World!" | 一个字符串(文本数据) | 要被显示的那段文字,用引号包起来 |
整句话翻译成大白话就是:「调用名为 print 的功能,把引号里的文字显示到屏幕上」。
print("Hello, World!") 的结构:函数名 + 括号 + 字符串。函数和字符串在第 4、5 章会深入展开。🧠 一句话记忆 print(某物) = 把「某物」显示到屏幕上。函数名 + 括号 + 要处理的数据,这个「三段式」是后续一切代码的骨架。
Hello, World 的两个幕后细节
第一个细节:这句话的「祖师爷」。1972 年前后,贝尔实验室的教程文档第一次用「让机器打个招呼」当作示例;后来一本影响深远的 C 语言教材沿用它开篇,从此「新语言的第一课 = Hello, World」成了全球惯例。它被选中的理由很实在:一行代码,就能同时验证「环境装好了、能建文件、能运行、能输出」四件事——本质上是一次最小化的全链路自检。你以后每到一个新环境(新电脑、新服务器、新容器),跑通它的第一个程序都应该是这句老话。
第二个细节:保存文件时的编码。源代码文件是纯文本,中文注释能否正常显示取决于文件用什么编码保存——请把编辑器的默认编码设为 UTF-8。要是你在别人电脑上打开代码看到满屏乱码,第一反应就该是「查编码」,而不是怀疑代码坏了。这个话题在第 5 章讲字符与字符串时会正式展开。
还有一个值得知道的演化细节:print 后面的括号并不是从来就有的。早年的 Python 2 里,print 是一种「语句」,写 print "Hello" 不带括号也能跑;Python 3 把它统一改成了函数,必须写括号。这次改动当年引发不少争论,但方向是对的:「显示数据」和「计算数据」一样,都规规矩矩走「名字 + 括号」的调用格式,整个语言的一致性更好了。你在网上查资料时如果撞见不带括号的 print,多半是 Python 2 时代的老代码——认得出它,也是一种本领。
📐 例题 4 print 与「计算器式」即时运算
在 Python 的交互模式(REPL,见 3.5 节)里依次做三个小实验,先预测输出、再实际运行核对:(1) 直接输入 123 * 456;(2) 直接输入 "2" + "3";(3) 输入 print(2 + 3)。
思路 REPL 里敲一个表达式、回车,就立刻看到结果——像一台随身的科学计算器。预测的关键在 (2):引号包起来的东西是文本不是数字,「加」在文本世界里的含义是「拼接」。
解 (1) 数值乘法:123 × 456 = 56088。(2) 字符串拼接:"2" + "3" 把两段文字首尾相接,得到 '23'——一个字符串,不是二十三。(3) 数值加法再打印:print(2 + 3) 输出 5。三个实验用程序核验:
print(123 * 456) # 数值:56088
print("2" + "3") # 字符串拼接:23
print(2 + 3) # 数值加法:5
运行输出:56088、23、5。(1)(2) 两个实验数字相同、含义迥异——「2」这个字符的平方既不是 4,也不是 22,而是把两个字符排在一起。
答:(1) 56088;(2) 23(字符串拼接);(3) 5(数值加法)。 ⚠ 易错点:引号改变身份——加了引号就是文本、参与「拼接」;不加引号就是数值、参与「算术」。这一对区别是第 4、5 章「类型」概念的第一颗种子,请把它记牢:从今天起,看到一个值,先问「它是什么类型」。
把例题 4 的发现放大成工程习惯:REPL 就是一台随身的工程计算器。现场要验算一个单位换算、心算没把握的一笔数、想快速试一下「这个函数到底返回什么」——开个 REPL 敲一行,答案立刻回来,比掏手机计算器还快,而且能连着上一步的结果继续算。工程师的键盘上,这个「问一句答一句」的窗口,是最高频打开的工具之一。
关于 print 再透露一个马上会用到的小本领:它一次不止能显示一样东西。试试 print("合格数:", 8)——用逗号把文字和数字隔开传给它,输出会是 合格数: 8,中间自动补了一个空格。这样一来,「给人看的报告」就不必把数字硬拼进文字里。为什么会有这个效果、逗号在这里叫什么名字,第 4 章讲函数参数时会正面回答——现在你只需知道:print 的本领比初见时大。
3.5程序从代码到输出的完整旅程
现在我们把整条链串起来,看你在命令行敲下 python hello.py 回车后,一分钟内发生了什么:
- 启动解释器:命令
python让系统找到并启动 Python 解释器。 - 读取源码:解释器打开
hello.py,读入里面的文字print("Hello, World!")。 - 逐行翻译执行:解释器把这行代码翻译成机器能懂的指令,交给 CPU 执行。
- 执行 print:CPU 执行后,效果是把 "Hello, World!" 这串文字送到屏幕。
- 程序结束:没有更多代码了,解释器退出,命令行重新等你输入。
核心思想 你现在写的每一行 Python 代码,都不是「魔法」,而是交给解释器翻译、再交给 CPU 执行的一串指令。理解这条链,你就再也不会觉得「程序运行」是黑箱了。
REPL vs 脚本:一对分工不同的搭档
其实从上一节开始,你已经在两种「使用 Python 的方式」之间穿行了,现在正式把它们摆上台面。脚本方式:把代码写进 .py 文件,用 python 文件名 整份执行——上面五步旅程说的就是它。REPL 方式(Read-Eval-Print Loop,读取-求值-打印循环):在命令行只敲 python 不带文件名,解释器打开一个交互窗口,出现 >>> 提示符,你敲一行、它应答一行,直到你退出。两者跑的是同一个解释器,差别只在「喂代码的方式」:脚本是一口气喂整份,REPL 是一口一口喂。
逐行执行还有一个对日常开发影响很大的推论:错误在哪一行,程序就停在哪一行。脚本从头跑到出事的那行为止,前面的行已经执行完毕、效果保留;REPL 则更宽容——上一行敲错了,改掉重敲就行,不用从头来过。这就是为什么试错、探索用 REPL 舒服:每一次「改一点、再看一眼」的循环都最短。
>>> 是它「请讲」的提示符。这也带出了本书从头到尾的练习方法:凡是新概念,先扔进 REPL 里戳一戳。学到一个新函数,别急着写进大程序,先在 REPL 里喂它两三个不同的输入,看它吐什么——像做小规模试验一样做「概念试验」。一次 REPL 探索,比读三遍文字描述更能建立直觉;等你能在 REPL 里预测出它的行为,再把它正式写进脚本也不迟。这个「先试验、后组装」的节奏,正是工程师面对陌生设备的标准姿势,用在语言学习上同样有效。
📐 例题 5 同一行代码,REPL 有输出、脚本没动静?
学员甲在 REPL 里敲 1 + 2,回车立刻看到 3。学员乙把同样的三个字符写进 a.py 文件,运行 python a.py,屏幕却毫无输出、命令直接结束。谁的操作错了?为什么会出现这种差异?如何让乙的脚本也显示 3?
思路 先回忆两种方式的机制差异:REPL 的全名是「读取-求值-打印循环」——它对每一行都做三件事:读入、求出值、自动把值打印给你看。脚本模式只做前两步,打印必须由你自己显式要求。所以不是谁错了,是「自动应答」这项服务只有 REPL 提供。
解 实际验证(两个文件都真实运行过):
# 文件一 a.py 的内容只有一行:
1 + 2
# 运行 python a.py —— 屏幕无任何输出,直接结束
# 文件二 b.py 的内容只有一行:
print(1 + 2)
# 运行 python b.py —— 屏幕显示:3
结论得到实测印证:1 + 2 这行在两种模式下都被「求值」出了 3,但脚本模式里这个 3 没有任何出口——REPL 的「自动打印」是它独有的交互服务,脚本里必须用 print() 自己把结果送出来。
答:谁都没操作错。REPL 自动回显表达式的值,脚本不会;让脚本显示 3,把该行改成 print(1 + 2)。 ⚠ 易错点:这是新手最高频的困惑之一,请把机制记住——「算出值」和「显示值」是两个独立动作:解释器永远负责算,显示要么 REPL 送(自动),要么 print 送(显式)。将来你写的脚本「跑完了却没结果」,第一反应就查:是不是忘了 print?
给这对搭档一张分工对照表,替你未来的日常工作做决定:
| 维度 | REPL(交互模式) | 脚本文件(.py) |
|---|---|---|
| 定位 | 草稿纸:试探、验算、查函数行为 | 正式文件:可重复、可留档 |
| 代码留存 | 随会话关闭而消失(除非专门保存) | 永久保存在文件里 |
| 适合长度 | 一两行的即问即答 | 十几行以上的完整任务 |
| 改错方式 | 敲错了,当场改一行重敲 | 改完存盘,重新运行整份 |
| 工程场景 | 现场快速验算、试函数用法 | 试验数据处理、批量任务、留痕报告 |
工程数据工作里有一条不成文的铁则:「试验型」的探索进 REPL,「交付型」的计算进脚本。凡是将来要给别人看、要复现、要追溯的计算,哪怕只有五行,也写成 .py 文件保存——因为脚本连同它的运行结果一起构成「计算留痕」;REPL 里算出的东西,关掉窗口就散了。第 11 章讲文件读写时,这条铁则会升级成完整的工程实践。
最后把这一章放进整本书的路线图里:到这里,你的「环境」已经完全就绪——解释器会装会验、代码会写会跑、REPL 会问会答、出错知道从哪查起。从第 4 章开始,我们将正式进入编程的核心内容:变量与内存。写作策略也会升级:每章的例题会越来越像真实的工程任务,而不再只是演示概念的小实验。请保持本章建立的动手习惯——每段代码都亲手跑一遍,每个结果都自己预测一遍再验证——它比任何阅读技巧都更能让你把这门手艺学到手。
本章小结
- 推荐 Python 入门,因为它语法接近人话、代码少、用途广;但真正要学的是编程思维。
- 编译是整本翻译一次,解释是一句一句边翻边执行;Python 是解释型语言。
- 解释器就是把 Python 代码翻译成机器码、并驱动 CPU 执行的程序。
- 第一个程序
print("Hello, World!")的结构:函数名 + 括号 + 字符串。 - 程序运行 = 解释器读源码 → 翻译 → CPU 执行 → 输出,一条清晰的因果链。
- PATH 是系统查找命令的目录清单;「Add Python to PATH」就是登记安装目录;改完环境变量要重开终端才生效。
- REPL 敲一行立刻应答,适合试探验算;脚本整份执行、永久留档,适合交付留痕。
- 「算出值」和「显示值」是两个动作:REPL 自动回显表达式的值,脚本必须显式
print()——引号还改变值的身份("2"+"3" 是拼接不是加法)。
读完本章,你应该能……
- 说清「编译」和「解释」的区别,并指出 Python 属于哪一种。
- 在自己的电脑上装好 Python,并用
python --version验证成功。 - 新建一个
.py文件,写出并运行你的第一个程序。 - 逐字解释
print("Hello, World!")每个部分的作用。 - 描述从「敲命令」到「看到输出」的完整旅程。
- 解释 PATH 的作用,并诊断「'python' 不是内部或外部命令」这类问题。
- 在 REPL 里完成一次即时报错的试探与重试,体会它比脚本短在哪。
- 说出「脚本里写了 1 + 2 却没输出」的原因与两种修法。
思考题
1. 「编译」和「解释」的本质区别是什么?用「翻译一本书」来类比。
提示:编译=先把整本书翻译好再出版(生成机器码文件);解释=现场同声传译,说一句翻一句,没有成品书。
2. 为什么 Windows 安装 Python 时建议勾选「Add Python to PATH」?
提示:勾选后系统才能在任意目录找到 python 命令,否则命令行会提示找不到。
3. 在 print("Hi") 里,print、()、"Hi" 分别扮演什么角色?
提示:print 是函数名(功能),括号是调用信号,引号里是传给函数的字符串数据。
4. 如果把 print("Hello") 写错成 prnt("Hello") 会发生什么?为什么?
提示:会报错,因为 Python 里没有名为 prnt 的功能;这正体现了第 1 章说的「零容错」。
5. 学员在 macOS/Linux 上敲 python --version 报「command not found」,但敲 python3 --version 正常。最可能的原因是什么?
提示:这类系统习惯把新版本命名为 python3,python 这个名字可能指向旧版本或不存在;属于例题 3 情形 B/C 的变体——先查「系统找到的到底是谁」。
6. 为什么 REPL 里敲 1 + 2 立刻显示 3,而脚本里写同一行却毫无输出?
提示:REPL 的 P 就是 Print——它对每行自动回显求值结果;脚本只求值不显示,要看到结果必须写 print(1 + 2)。
7. 现场快速验算一个单位换算,和出具一份可追溯的正式计算报告,分别该用 REPL 还是脚本?为什么?
提示:验算用 REPL——即问即答、试错成本最低;正式报告用脚本——代码永久留档、任何人任何时间可复现,与工程「计算留痕」的要求一致。
8. 静态类型语言里已声明 int x; 的变量,被赋一个字符串会怎样?Python 里做同样的事呢?
提示:静态类型在翻译/检查阶段就报错拦下,程序根本跑不起来;Python 运行到那一行才会抛出 TypeError,而且在那之前同一个名字完全可以先是整数、后变字符串。「错误暴露得早」和「写得灵活」,正是两种类型风格的典型差异。
9. 装好 Python 后,写第一行代码前为什么要先敲 python --version?这一步在工程上叫什么?
提示:一是确认 PATH 已通——系统真的找得到这位「翻译官」;二是确认版本与教程、团队环境一致——不同版本之间语法与内置库有差异。「先验环境、再写代码」是工程基本功:环境不对,后面每一步都白费。