Python 既是解释型语言,也是编译型语言

不知道有没有小伙伴跟我一样,刚开始学习 Python/ target=_blank class=infotextkey>Python 的时候都听说过 Python 是一种解释型语言,因为它在运行的时候会逐行解释并执行,而 C++ 这种是编译型语言

Python 既是解释型语言,也是编译型语言

文章插图
图片
不过我今天看到了一篇文章,作者提出 Python 其实也有编译的过程,解释器会先编译再执行
不但如此,作者还认为【解释】与【编译】是错误的二分法、限制了编程语言的可能性 。Python 既是解释型语言,也是编译型语言!
本文文字较多,干货满满,耐心看完相信你会有不小的收获
原文:https://eddieantonio.ca/blog/2023/10/25/python-is-a-compiled-language/
前 言本文所说的 Python,不是指 PyPy、Mypyc、Numba、Cinder 等 Python 的替代版本,也不是像 Cython、Codon、mojo1这样的类 Python 编程语言
我指的是常规的 Python——CPython
目前,我正在编写一份教材,教学生如何阅读和理解程序报错信息(programming error messages) 。我们正在为三种编程语言(C、Python、JAVA)开设课程
程序报错信息的本质的关键点之一在于程序报错是在不同阶段生成的,有些是在编译时生成,有些是在运行时生成
第一门课是针对 C 语言的,具体来说是如何使用 GCC 编译器 , 以及演示 GCC 如何将代码转换成可执行程序
  • 预处理(preprocessing)
  • 词汇分析(lexical analysis)
  • 语法分析(syntactic analysis)
  • 语义分析(semantic analysis)
  • 链接(linking)
除此之外,这节课还讨论了在上述阶段可能出现的程序报错 , 以及这些报错将如何影响所呈现的错误消息 。重要的是:早期阶段的错误将阻止在后期阶段检测到错误(也就是说 A 阶段的报错出现之后,B 阶段就算有错误也不会检测出来)
当我将这门课调整成针对 Java 和 Python 时,我发现 Python 和 Java 都没有预处理器(preprocessor),并且 Python 和 Java 的链接(linking)不是同一个概念
我忽略了上面这些变化 , 但是我偶然发现了一个有趣的现象:
编译器在各个阶段会生成报错信息,而且编译器通常会在继续执行之前把前面阶段的报错显示出来,这就意味着我们可以通过在程序中故意创建错误来发现编译器的各个阶段
所以让我们玩一个小游戏来发现 Python 解释器的各个阶段
Which is the first error ?我们将创建一个包含多个 bug 的 Python 程序 , 每个 bug 都试图引发不同类型的报错信息
我们知道常规的 Python 每次运行只会报告一个错误,所以这个游戏就是——哪条报错会被首先触发
Python 既是解释型语言,也是编译型语言

文章插图
图片
每行代码都会产生不同的报错:
  • 1 / 0将生成 ZeroDivisionError: division by zero
  • print() = None 将生成 SyntaxError: cannot assign to function call
  • if False 将生成 SyntaxError: expected ':' .
  • ñ = "hello 将生成 SyntaxError: EOL while scanning string literal .
问题在于,哪个错误会先被显示出来?需要注意的是:Python 版本很重要(比我想象的要重要),所以如果你看到不同的结果,请记住这一点
PS:下面运行代码所使用的 Python 版本为 Python 3.12
在开始执行代码之前,先想想【解释】语言和【编译】语言对你来说意味着什么?
下面我将给出一段苏格拉底式的对话,希望你能反思一下其中的区别
苏格拉底:编译语言是指代码在运行之前首先通过编译器的语言 。一个例子是 C 编程语言 。要运行 C 代码 , 首先必须运行像  or clang 这样的 gcc 编译器 , 然后才能运行代码 。编译后的语言被转换为机器代码 , 即 CPU 可以理解的 1 和 0 。
柏拉图:等等,Java不是一种编译语言吗?
苏格拉底:是的,Java是一种编译语言 。
柏拉图:但是常规 Java编译器的输出不是一个 .class 文件 。那是字节码,不是吗?
苏格拉底:没错 。字节码不是机器码,但 Java 仍然是一种编译语言 。这是因为编译器可以捕获许多问题,因此您需要在程序开始运行之前更正错误 。


推荐阅读