1. Python 演进史:从 Python 2 到 Python 3 的变迁
聊 Python 的演进史,其实就是在聊一个语言怎么「断臂求生」。我入行那会儿,Python 2.7 还是的主流。那时候公司里老项目全是 2.x 的代码,谁提 Python 3 谁就是找麻烦。但你看现在,还有谁用 Python 2?
这背后不是简单的版本升级,而是一次近乎「自残」的主动淘汰。今天我们就来拆一拆,Python 到底经历了什么。
1.1 为什么会有 Python 2 和 Python 3 的分裂?
说白了,Guido van Rossum(Python 之父)在 2000 年代初发现了一个问题:Python 2 的设计有些「历史遗留硬伤」,改起来会破坏向后兼容。不改,语言会越来越臃肿;改,社区会分裂。
他选了后者。2008 年,Python 3.0 发布,带着一堆不兼容的改动。我记得当时很多开发者直接炸了——「凭什么我的 print 语句要加括号?」
核心矛盾:Python 2 的「字符串/字节串混用」和「整数除法截断」是两大痛点。Python 3 一刀切,但代价是社区花了近 10 年才完成迁移。
1.2 关键版本特性对比
我挑几个最影响日常开发的差异,列个表。你写代码时大概率会碰到这些坑。
| 特性 | Python 2 | Python 3 |
|---|---|---|
| print 语句 | print "hello" |
print("hello") |
| 整数除法 | 5 / 2 返回 2 |
5 / 2 返回 2.5 |
| 字符串编码 | str 是字节串,unicode 是文本 | str 是 Unicode,bytes 是字节串 |
| 异常语法 | except Exception, e: |
except Exception as e: |
| range 行为 | 返回列表 | 返回迭代器(类似 xrange) |
| input 函数 | eval(raw_input()) | 直接返回字符串 |
我个人的习惯:迁移老项目时,先跑一遍 2to3 工具,但别全信它。字符串编码那块,它经常改出 bug。我一般手动过一遍所有 open() 的 encoding 参数。
1.3 为什么 Python 2 被淘汰?
不是 Python 2 不好,而是 Python 3 已经足够好,社区没精力维护两套了。2020 年 1 月 1 日,Python 2 正式停止支持。嗯,这个日期我记得很清楚——那天我还在改一个遗留系统的编码问题。
具体原因有三点:
- 安全风险:不再有官方安全补丁。你想想看,一个公开了漏洞却没人修的语言,谁敢用在生产环境?
- 生态迁移:主流库(Django、Flask、NumPy、Pandas)在 2018-2020 年间陆续停止支持 Python 2。你不升级,就等于用不了新版本。
- 新特性缺失:类型注解、f-string、异步编程(async/await)、数据类(dataclass)——这些现代 Python 的杀手级功能,Python 2 一个都用不上。
我曾经踩过的坑:2021 年接手一个项目,对方说「代码是 Python 2 的,但跑得好好的」。结果一查,依赖的第三方库有 3 个已经 2 年没更新,其中一个是安全相关的。最后花了 2 周做迁移,期间还因为编码问题崩了一次线上服务。别拖,真的别拖。
1.4 知识体系总览
下面这张图,把 Python 从 2 到 3 的核心变迁串起来了。你可以把它当作本章的「地图」。
1.5 一个简单的代码对比
光说不练假把式。我们看一段实际代码,感受一下差异。
# Python 2 写法
name = raw_input("请输入你的名字:")
print "你好, " + name
print "你的年龄是: " + 25 # 这里会报错,因为字符串不能直接拼接整数
# Python 3 写法
name = input("请输入你的名字:")
print(f"你好, {name}")
print(f"你的年龄是: {25}") # f-string 自动处理类型转换
我建议:如果你还在维护 Python 2 代码,至少先把 from __future__ import print_function, division 加上。这样能让代码更接近 Python 3 的写法,后续迁移会省很多事。
1.6 迁移的「痛苦指数」
说实话,Python 2 到 3 的迁移,痛苦程度取决于你的代码风格。我总结了一个经验公式:
- 纯计算脚本:几乎无痛。改改 print、除法,半天搞定。
- Web 应用:中等痛苦。字符串编码、数据库连接、模板渲染都可能出问题。
- 遗留系统 + 大量二进制数据处理:高痛苦。bytes/str 的混用会让你怀疑人生。
我曾经帮一个金融客户迁移他们的交易系统。代码里到处都是 str 和 unicode 的隐式转换,光修编码 bug 就花了两周。嗯,那之后我养成了一个习惯:新项目一律用 Python 3,绝不回头。