写点什么

为什么 Cpython 是 C 写的,而不是 Python

作者:宇宙之一粟
  • 2022 年 1 月 27 日
  • 本文字数:1957 字

    阅读完需:约 6 分钟

为什么 Cpython 是 C 写的,而不是 Python

CPython 中的 C 是指 C 语言,意味着这个 Python 默认发行版是用 C 语言编写的。其实,CPython 的编译器是用纯 C 语言编写的,或者是 C 和 Python 的组合。那我们不经要问:

为什么 Cpython 不是用其他语言

我们首先要知道,高级语言都要编译为机器语言。所以区别就在于编译器的工作方式中,有两种类型的编译器:


  1. 自我实现编译器:如 Go 语言,一开始也是 C 语言实现的编译器,后面逐渐使用 Go 重写编译器;

  2. 源到源编译器:是用另一种已经有编译器的语言编写的编译器。开发新语言时用已经完善且成熟的编译器编写,节省时间和学习成本。


Python 解释器中默认和最流行实现是 CPython 。使用它有一个重要的优势。C 是编译语言,其代码转换为机器代码,由中央处理单元(CPU)直接执行。


为什么 Python 最常见的解释器是 C 语言编写的,那为什么不是 Python 或者 C++ 等编程语言呢?


这是一种实用和历史原因的组合。(主要是)历史原因是 CPython 1.0 于 1989 年发布。当时,C 最近是标准化的。C ++几乎是未知的并且明确不可移植,因为几乎没有人有 C ++编译器。


Linux 之父 —— Linus Torvalds 无敌不喜欢 C ++,并且多次向 C++ 表示抗议。


Python 之父 Guido 也没有表示对 C ++ 的那种强烈的负面情绪。


尽管 C++ 在今天更广泛且更容易获得,但将 CPython 重写为与 C++ 兼容的 C 仍需要大量工作。就其本身而言,这项工作几乎没有或根本没有真正的好处。

并非百分百的 C

C(CPython)中的 Python 实现不是 100% 编译的,也不是 100% 解释的。在运行 Python 脚本的过程中,既有编译也有解释。为了清楚起见,让我们看看运行 Python 脚本的步骤:


  • 使用 CPython 编译源代码生成字节码

  • 在 CPython 解释器中解释字节码

  • 在 CPython 虚拟机中运行 CPython 解释器的输出


当 CPython 编译源代码(.py 文件)来生成 CPython 字节码(.pyc 文件)时,会进行编译。然后使用 CPython 解释器解释 CPython 字节码(.pyC 文件),输出在 CPython 虚拟机中运行。根据上述步骤,运行 Python 脚本的过程同时涉及编译和解释。


CPython 编译器仅生成一次字节码,但每次代码运行时都会调用解释器。通常对字节码的解释需要很多时间。如果使用解释器慢下来,为什么要使用它?大的原因是它有助于使 Python 跨平台。由于字节码在 CPU 的顶部的 CPython 虚拟机中运行,因此它独立于它运行的机器。因此,字节码可以不变地运行不同的机器。


CPython 保持其 C 的传统:许多标准库模块,如 ssl 模块或 sockets 模块,都是用 C 写好的,用以访问底层操作系统 API。Windows 和 Linux 内核中用于创建网络 sockets 的 API、使用文件系统和与显示交互的都用 C 编写。


Python 专注于 对 C 语言层面上的扩展。


如果没有使用解释器,那么 CPython 编译器将生成直接在 CPU 中运行的机器代码。因为不同平台有不同的指令,所以代码不会跨平台。


总之,使用编译器加快过程,但解释器使代码跨平台。因此,Python 比 C 慢的原因是使用解释器。请记住,编译器刚刚运行一次,但每次执行代码时都会运行解释器。


Python 比 C 慢得多,但许多程序员仍然更喜欢它,因为它更容易使用。Python 从程序员隐藏了许多细节,这可以帮助防止令人沮丧的调试。例如,由于 Python 是一种动态键入的语言,您不必明确指定代码中的每个变量的类型 - Python 将自动推断出来。相比之下,具有静态类型语言(如 C,C ++ 或 Java),您必须指定变量的类型,如下所示。


int x = 2022string s = "Hello, World"
复制代码


将此与以下 Python 中的实现进行比较。动态类型使编码更容易,但增加了机器寻找合适数据类型的负担。这会使过程变慢。


x = 2022s = "Hello, World"
复制代码


一般来说,像 Python 这样的“更高级别”语言更容易用于开发人员。但是,当运行代码时,需要将其转换为低级指令。简单易用的这种转换带来的牺牲是需要更多的时间。


如果时间是一个重要因素,那么您需要使用较低级别的指令。比如直接使用 C 语言、C++ 或者时兴的 Rust。

总结

当然,如今,CPython 不再是唯一的 Python 实现。还有如下的 Python 解释器:


  • Stackless Python(支持微线程的 CPython 分支)

  • IronPython(在 .NET 上运行的 Python)

  • Jython(在 Java 虚拟机上运行的 Python)

  • PyPy(带有 JIT 编译器的快速 python 实现)

  • RPython(Python 的静态类型子集)编写的 PyPy

  • NQP 和 PIR 中的 Pynie 等等


总结就是众多的历史原因让吉多大叔选择了用 C 语言写出 Python 的解释器,而 Python 的设计原则为了追求简洁的语法牺牲了一定的时间,所以官方默认的解释起依旧是 CPython。

而为了开发者的方便,时至今日,还有更多其他的解释器版本,而不是弃用原有的 CPython 的底层 API ,选择用 Python 自我实现的解决方案。

好了,这就是为什么 CPython 不用其他语言实现的原因了,希望您看到这里能有帮助。

下一篇文章见!

灵感来源:https://realpython.com/cpython-source-code-guide/

发布于: 刚刚阅读数: 2
用户头像

宇宙古今无有穷期,一生不过须臾,当思奋争 2020.05.07 加入

🏆InfoQ写作平台-第二季签约作者 🏆 混迹于江湖,江湖却没有我的影子 热爱技术,专注于后端全栈,轻易不换岗 拒绝内卷,工作于软件工程师,弹性不加班 热衷分享,执着于阅读写作,佛系不水文

评论

发布
暂无评论
为什么 Cpython 是 C 写的,而不是 Python