当前位置:首页>python>Python 2与Python 3:开发者不可忽视的现实差异

Python 2与Python 3:开发者不可忽视的现实差异

  • 2026-08-25 12:15:30
Python 2与Python 3:开发者不可忽视的现实差异

这个话题在论坛上已经基本平息,但在现实世界中仍未消亡。开发者在旧的内部系统、存档脚本或尚未现代化的维护项目中仍会碰到Python 2。

问问任何运维或质量保证团队的人——你仍然会在服务器上看到它,或者更糟糕的是,它被埋藏在部署脚本中。这门语言从技术上讲已经“结束”,但它的影响太大,不可能一夜之间消失。

所以,这不再是关于理论或版本争论的问题。而是关于实际应用。如果你以任何严肃的方式使用Python,了解Python 2和Python 3之间的主要区别是有用的,因为你可能需要同时接触两者——即使是现在。

以下是你真正需要知道的要点。没有废话。

基础:语法看起来如何

让我们从每个人都会立即遇到的事情开始:打印文本。

在Python 2中尝试这个:

print"this runs"

现在在Python 3中做同样的:

print("this also runs")

在Python 2中,print只是一个关键字。不需要括号。但在Python 3中,print是一个函数,所以它需要括号,否则会抛出错误。仅这一变化就使得从2到3的迁移变得很烦人,如果你试图移植旧脚本或混合版本。

单独来看,这不是什么大问题。但它几乎出现在每个文件中。

算术:意想不到的结果

除非你仔细观察,否则你不会注意到这一点。尝试除以整数:

Python 2:

x = 9 / 5# 给你 1(整数数学)

Python 3:

x = 9 / 5# 给你 1.8

在2中,除以整数得到的是……整数。在3中,除法给你浮点数,除非你强迫它不这么做。

有一次,我花了一个小时调试一个报告工具中的四舍五入错误,就是因为这个。脚本最初是用Python 2编写的,然后原样传下来。另外,Python 2允许你通过从未来模块导入真正的除法来修复这个问题,但人们很少记得这样做。

如果你在遗留代码中看到奇怪的数字输出,怀疑整数除法。

字符串在奇怪的地方断开

事情在这里变得更加混乱。

在 Python 2 中:

word = "naïve"

实际上,如果不在前面加上 "u",它会被存储为一个字节字符串:

word = u"naïve"

没有 "u",某些字符会根据终端或解释器的不同而断开或表现异常。Python 2 默认使用普通字节,这是许多 UnicodeDecodeErrors 的根源。

在 Python 3 中,默认情况下字符串是 Unicode。正是你期望的那样。如果你想要原始字节,你必须声明:

raw = b"naïve"

这种区分使得 Python 3 中的字符串处理更加可预测。在 API、文件处理或电子邮件内容中尤其重要。

冗长的循环 & 范围

Python 2 有两个选项:

  • range() - 返回一个列表
  • xrange() - 生成器(内存高效)

基本规则:对于大循环,使用 xrange(),这样你就不会构建巨大的列表。

Python 3 将它们合并了。range() 的行为像旧的 xrange()。示例:

for i in range(1000000):  # 在内存中不会构建一个巨大的列表
    pass

更干净。同时,xrange 在 Python 3 中被移除了,所以如果你在代码中看到它,这会立即告诉你你正在使用哪个 Python 版本。

异常风格

你可能不会在意的一件事,直到它破坏了你的脚本:

Python 2:

try:
    fail_something()
except ValueError, e:
    print e

Python 3:

try:
    fail_something()
except ValueError as e:
    print(e)

这个变化很小但很重要。一些工具在迁移过程中处理它,一些则不处理。它几乎总是被 linters 或解释器捕获,但不是在你浪费大量时间之前,如果你对那行代码不熟悉的话。

输入差异

人们经常忘记这一点:

Python 2:

  • raw_input() → 返回一个字符串
  • input() → 将输入评估为 Python 代码(危险)

Python 3:

  • input() 只返回一个字符串

所以如果你在运行用户输入代码并且得到奇怪的结果或错误,请检查它是在 2 还是 3 上运行,以及你是否错误地使用了 raw_input。

如果你正在维护一个旧的命令行界面(CLI)应用程序,而它突然开始在你输入数字时抛出NameError,这可能是原因。

字典迭代

在Python 2中有一个字典吗?

这两个是不同的:

my_dict.items()  # 构建一个静态列表
my_dict.iteritems()  # 返回一个生成器(节省内存)

在Python 3中,.items()返回一个视图,其工作方式类似于生成器。iteritems()已经不存在了。

这个小差异在你处理大型JSON文件或配置时会显现出来。如果你在Python 2中优化速度/内存,然后移植到3,如果你忘记重新审视这一点,可能会得到奇怪的性能波动。

库支持和生态系统

大多数有意义的库不再支持Python 2了。Django、Requests、Numpy、Pandas——所有当前版本都是Python 3。

你有时可以安装旧版本,但那些版本有它们自己的问题:漏洞、不稳定、缺乏特性。

如果你试图在旧项目中启动一个虚拟环境或使用pip安装,而事情崩溃了,这通常是原因。

此外,Python 2在现代工具上的依赖解析更加困难。

官方支持在2020年停止了,但实际上,大多数开源维护者在那之前就已经转移了。

顽固的遗留系统

我偶尔还会遇到一种情况:2010-2014年左右构建的内部工具和服务从未获得迁移预算。

通常你会发现Python 2为它们提供动力,通过cron运行或设置为后端工作器。

开发者多年前就离开了,没有人愿意触碰部署脚本。你将生命迹象修补得足够长,以保持运行,最终才会有人升级堆栈。

如果这就是你——我理解。有时业务方面会延迟重写,即使技术方面已经准备好。

结语

如果你今天从头开始,就直接使用Python 3。

如果您正在维护一些较旧的东西,了解差异会有很大帮助。您可以节省时间,避免尴尬的错误,并在移植旧工具时建立信心。

2和3之间的这些变化大多是合乎逻辑的。但它们并不兼容,所以即使是小事——比如字符串格式化或循环范围——如果您不了解发生了什么,也可能悄无声息地爆炸。

在混合环境中,精通两者不仅仅是个人喜好的问题,更是生存的问题。

无

最新文章

随机文章