python-ideas 的新手偶尔会提到“Python 4000”的想法,他们提出一些向后不兼容的更改,但没有提供从当前合法的 Python 3 代码进行迁移的明确途径。 毕竟,我们允许 Python 3.0 进行这种更改,那么为什么我们不允许 Python 4.0 进行这种更改呢?
我已经听到过足够多次这个问题了(包括更令人担忧的措辞“你曾经进行过一次大的向后兼容性破坏,我怎么知道你不会再做一次?”),所以我认为我应该在这里记录下我的答案,这样将来就可以将人们引导到这里。
目前对 Python 4.0 有什么期望?
我目前的期望是 Python 4.0 仅仅是“Python 3.9 之后的版本”。 仅此而已。 语言上没有深刻的变化,也没有重大的向后兼容性破坏 - 从 Python 3.9 升级到 4.0 应该像从 Python 3.3 升级到 3.4(或从 2.6 升级到 2.7)一样顺利。 我甚至期望稳定的应用程序二进制接口(最初在PEP 384中定义)能够跨越这个界限得到保留。
按照目前的语言特性发布速度(大约每 18 个月一次),这意味着我们可能会在 2023 年的某个时候看到 Python 4.0,而不是看到 Python 3.10。
那么 Python 将如何继续发展?
首先,Python 增强提案流程没有任何改变 - 向后兼容的更改仍然会被不断提出,新的模块(例如 asyncio
)和语言特性(例如 yield from
)被添加进来,以增强 Python 应用程序可用的功能。 随着时间的推移,Python 3 将继续在默认提供的功能方面超越 Python 2,即使 Python 2 用户可以通过第三方模块或从 Python 3 的反向移植来访问等效的功能。
竞争性的解释器实现和扩展也将继续探索增强 Python 的不同方式,包括 PyPy 对 JIT 编译器生成和软件事务内存的探索,以及科学和数据分析社区对数组导向编程的探索,该编程充分利用了现代 CPU 和 GPU 提供的矢量化功能。 与其他虚拟机运行时(如 JVM 和 CLR)的集成也有望随着时间的推移而得到改善,特别是由于 Python 在教育领域取得的进展可能会使其在这些环境中运行的更大的应用程序中作为嵌入式脚本语言变得越来越受欢迎。
对于向后不兼容的更改,PEP 387 提供了一个合理的概述,介绍了 Python 2 系列多年来使用的方法,并且今天仍然适用:如果某个功能被认为存在过度的问题,那么它可能会被弃用并最终被删除。
然而,开发和发布过程中的一些其他更改使得 Python 3 系列中不太需要此类弃用。
- CPython 核心开发团队与 Python Packaging Authority 之间的合作,以及 Python 3.4+ 中捆绑的
pip
安装程序表明,更加强调 Python 包索引,这减少了在标准库中添加模块的压力,在它们足够稳定之前,以适应相对较慢的语言更新周期。 - "临时 API" 概念(在 PEP 411 中引入)使得可以在提供标准向后兼容性保证之前,对那些被认为可能从更广泛的反馈中获益的库和 API 应用 "稳定期"。
- 在 Python 3 过渡中,许多积累的遗留行为实际上已被清除,现在对 Python 和标准库的新增功能的要求比 Python 1.x 和 Python 2.x 时代 *严格得多*。
- "单源" Python 2/3 库和框架的广泛开发强烈鼓励在 Python 3 中使用"记录在案的弃用",即使这些功能被更新的、首选的替代方案所取代。 在这些情况下,弃用通知会放置在文档中,建议新代码的首选方法,但不会添加程序化的弃用警告。 这允许现有代码(包括支持 Python 2 和 Python 3 的代码)保持不变(代价是新用户在负责维护现有代码库时可能会稍微多学一些东西)。
从(主要是)英语到所有书面语言
还值得注意的是,Python 3 并不像它最终表现出的那样具有破坏性。 在 Python 3 中所有向后不兼容的更改中,许多迁移的严重障碍都可以归咎于 PEP 3100 中的一个小要点:
- 使所有字符串都成为 Unicode,并拥有一个单独的 bytes() 类型。 新的字符串类型将被称为 'str'。
PEP 3100 是 Python 3 更改的所在地,这些更改被认为足够没有争议,不需要单独的 PEP。 这种特定更改被认为没有争议的原因是,我们在 Python 2 中的经验表明,Web 和 GUI 框架的作者是正确的:作为 *应用程序* 开发人员明智地处理 Unicode 意味着确保所有文本数据都尽可能接近系统边界地从二进制转换为文本,以文本形式操作,然后转换回二进制以进行输出。
不幸的是,Python 2 并不鼓励开发人员以这种方式编写程序 - 它广泛地模糊了二进制数据和文本之间的界限,使得开发人员很难在他们的头脑中将两者分开,更不用说在他们的代码中了。 因此,Web 和 GUI 框架的作者必须告诉他们的 Python 2 用户 "始终使用 Unicode 文本。 如果你不这样做,那么在处理 Unicode 输入时,你可能会遇到模糊且难以追踪的错误"。
Python 3 不同:它在 "二进制域" 和 "文本域" 之间施加了更大的分离,使得编写正常的应用程序代码更容易,同时使得编写与系统边界一起使用的代码稍微困难一些,在这种系统边界中,二进制和文本数据之间的区别可能明显不清楚。 我已经在 其他地方 更详细地介绍了 Python 2 和 Python 3 之间文本模型的实际变化。
Python 的 Unicode 支持的这场革命正在针对更大的背景展开,即计算文本操作从仅英语的 ASCII(正式定义于 1963 年)开始,通过 "二进制数据 + 编码声明" 模型的复杂性(包括 C/POSIX 区域设置 和 Windows 代码页 系统,于 1980 年代后期引入)和 Unicode 标准的初始 16 位版本(于 1991 年发布)到相对全面的现代 Unicode 代码点系统(首次定义于 1996 年,每隔几年发布新的主要更新)。
为什么要提到这一点? 因为这种切换到 "默认使用 Unicode" 是 Python 3 中最具破坏性的向后不兼容的更改,与其他更改(更多是语言特有的)不同,它是整个行业在文本数据表示和操作方式上进行更大规模变革的一小部分。 通过 Python 3 过渡清除语言特有的问题,与 Python 早期相比,新语言功能的准入门槛更高,并且目前没有其他像从 "带有编码的二进制数据" 切换到 Unicode 进行文本建模这样规模的行业范围的迁移正在进行中,我看不出会有任何类型的更改需要 Python 3 样式的向后兼容性破坏和平行支持期。 相反,我希望我们能够在正常的变更管理流程中适应未来的任何语言演变,并且任何无法以这种方式处理的提案都将被拒绝,因为它会对社区和核心开发团队施加不可接受的高成本。
最初发表在 Curious Efficiency,也可在 Red Hat 开发者博客 上找到。 根据 Creative Commons 重新发布。 有关 Python 演变的更多信息,您可能对 使用 Python 过渡到多语言编程 感兴趣,同样由 Nick Coghlan 撰写。
13 条评论