Python 是一门解释型语言:写好的代码不直接跑,先被翻成字节码,再由虚拟机逐条执行。 版本号第二位一变(3.12 到 3.13),第三方库就可能装不上——这是「版本」最实际的后果。 老的 print 语句在 3 里直接编译不过;7 / 2 在 2 里得 3,在 3 里得 3.5。
第 1 章讲的都是「为什么」;从这一章开始动手。 第 2 章一共八篇,全部围绕一件事:把环境搭起来,让代码能跑。 这一篇讲版本。看着简单,但「装错版本」是新手第一个大坑,而且它会在装库的时候才发作。
一、解释型是什么意思
编译型语言(C、Java)先整体翻成机器码,再运行。中间那步叫编译,产物能单独拿走。 Python 是解释型:源码先翻成「字节码」——一种中间形式,再交给虚拟机逐条执行。 字节码不直接变成机器码,所以 Python 比 C 慢。反过来,改一行不用等编译,改完就能跑。
代价换来的是迭代速度:试一个想法,从改到看到结果只要一秒。这对做数据分析很关键。
二、版本号的三段
Python 的版本号是三段:主版本.次版本.微版本,比如本篇跑在 3.13.14 上。
| 位置 | 含义 | 变了会怎样 |
|---|---|---|
| 第一段 3 | 主版本 | 语法大改,几乎不兼容(2 到 3 花了十年) |
| 第二段 13 | 次版本 | 加新语法,第三方库要重新编译 |
| 第三段 14 | 微版本 | 只修 bug,随便升 |
关键在第二段。 3.13 出来了,3.12 编好的那些 C 扩展(numpy、pandas 都在内)用不了,得等它们发布 3.13 的版本。 这就是为什么「昨天还好好的,今天装个库说找不到」——多半是次版本号对不上。
三、两句老代码,两个坑
第一句:print "hello"。这在 Python 2 里完全合法,在 3 里编译不过,报错原文是 Missing parentheses in call to 'print'. Did you mean print(...)?——提示很直白,让加括号。 第二句:7 / 2。在 2 里得 3(整数相除向下取整),在 3 里得 3.5。
第二个坑更阴:代码不报错,就是算错。本该 3.5 的地方拿到 3,误差 14%,还看不出异常。 要整除得写 7 // 2,要余数写 7 % 2,这三个写法在 3 里分工清楚。
四、怎么确认自己在用哪个
命令行敲 python -V,或者代码里读 sys.version_info。 后者能直接比较,比如 sys.version_info >= (3, 8)。 不要切版本号字符串来比较:「3.9」和「3.13」按字符串比,3.9 反而大。 本机是 3.13.14,major=3。写脚本时如果要兼容老版本,用元组比较。
五、该装哪个
一句话:装 3.x 里最新的稳定版。不装 2.x,不装预览版(版本号带 a 或 b 的)。 2.x 在 2020 年停止维护,现在装它等于开局就踩坑,而且大部分库已经不支持。 预览版(比如 3.14a1)是给库的作者试兼容性用的,普通用户装了会遇到一堆装不上的包。
这一节的全部意义就一条:别在版本上省事。后面装的每个库都要跟它对齐。
六、动手 Demo:同一行代码,三个版本三种结果
先打出版本号,再试编译一句 Python 2 的 print,最后看除法的两个答案。 这段代码在 Python 2 和 3 里跑出来的结果不一样,正是本篇要讲的。
import sys
print("版本 %s" % sys.version.split()[0])
print("三段 %d.%d.%d" % sys.version_info[:3])
src = "print 'hello'"
try:
compile(src, "<py2>", "exec")
print("老的 print 语句:能编译")
except SyntaxError as e:
print("老的 print 语句:编译失败")
print(" 报错:%s" % e.msg)
print("7 / 2 = %s" % (7 / 2))
print("7 // 2 = %d" % (7 // 2))
print("7 %% 2 = %d" % (7 % 2))
实跑输出:
--------------------------------------------------------------------
同一行代码,三个版本三种结果
--------------------------------------------------------------------
① 先看这台机器跑的是什么
--------------------------------------------------------------------
Python 的版本号是三段:主版本.次版本.微版本,这里是 3.13.14。
完整串:3.13.14 (main, Jun 11 2026, 04:04:46) [MSC v.1944 64 bit (AMD64)]。
教材用的是 3.x,所以本文所有代码按 Python 3 写。
! 版本号第二位一变(3.12 到 3.13),第三方库就可能装不上——这是「版本」最实际的含义。
② 老的 print 语句在 3 里根本编译不过
--------------------------------------------------------------------
「print 'hello'」这段代码:编译失败。
报错原文:Missing parentheses in call to 'print'. Did you mean print(...)?
原因是 Python 3 把 print 从「语句」改成了「函数」,必须写成 print("hello") 带括号。
! 这不是排版讲究。语句和函数是两种东西:函数能当参数传,语句不能。
③ 除法:同一个符号,两个答案
--------------------------------------------------------------------
在 Python 2 里,7 / 2 得 3——两个整数相除,结果向下取整。
在 Python 3 里,7 / 2 得 3.5,整除要写 7 // 2 得 3。
这一改让多少老代码算错了数:本该 3.5 的地方拿到了 3,误差不算小。
| 写法 | Python 2 | Python 3 |
|---|---|---|
| 7 / 2 | 3 | 3.5 |
| 7 // 2 | 3 | 3 |
| 7 % 2 | 1 | 1 |
! 所以看到「书上说结果是 3」先别急着改代码,先确认那本书是哪个年代写的。
④ 怎么查自己装的是哪个版本
--------------------------------------------------------------------
命令行里敲 python -V,或者代码里读 sys.version_info。
本机是 3.13.14,major=3。
! 写脚本时判断版本用 sys.version_info >= (3, 8),不要去切版本号字符串。
⑤ 版本选哪个
--------------------------------------------------------------------
一句话:装 3.x 里最新的稳定版,不要装 2.x,也不要装预览版(带 a 或 b 的)。
2.x 已经在 2020 年停止维护,现在装它等于开局就踩坑。
! 这一节的全部意义就一条:别在版本上省事。后面装的每个库都要跟它对齐。
compile 是内建函数,它只做「翻成字节码」这一步,不执行。用它来试语法最省事。
最后一行那个 %%:字符串里已经有 % 格式化,要打出一个百分号本身就得写两个。
这是本课后面反复出现的坑。
30 秒实验
- 把 7 / 2 换成 6 / 2,结果还是 3.0 吗?想想为什么。
- 查一下 sys.version_info 的完整内容,它一共几个字段?
- 想一想:为什么 Python 3 要把 print 从语句改成函数?函数比语句多了什么能力?
常见误区
- 按字符串比版本号:「3.9」比「3.13」大,这是字符串比较的结果,不是版本比较。
- 装预览版图新鲜:库还没适配,装十个包有八个失败。
- 以为改个 print 括号就迁移完了:除法、字符串编码、字典顺序都要查。
- 同时装好几个 Python 不管:PATH 里靠前的先被用上,你以为在用一个其实在用另一个。
自测三问(点开对答案)
1. 为什么次版本号(第二段)变化的影响比微版本大? —— 次版本会加新语法和新的 C 接口,第三方扩展要重新编译;微版本只修 bug,二进制兼容。 2. 7 / 2 在 Python 2 和 3 里分别得什么?为什么这是个危险的区别? —— 2 里得 3,3 里得 3.5。危险在于它不报错,只是悄悄算错,而且误差不小。 3. 判断版本该用什么写法? —— 用 sys.version_info >= (3, 8) 这样的元组比较,不要切字符串。版本定了,接下来把它装上。 下一篇讲装在哪、装完系统怎么找到它——也就是 sys.executable 和 sys.path 这两件事。
- ☐ (本篇完,下一篇 2.2 装上 Python 与自带的 IDLE)