关于编译:使用Python解释器时,是否使用了编译器?

When using the Python Interpreter, is the compiler used at all?

在Google的Python类中,它会读取

Python is a dynamic, interpreted (bytecode-compiled) language

我知道解释器是什么,知道字节码是什么,但两者似乎不合适。 在做了一些阅读后,基本上Python源代码在被解释之前自动编译就变得更加清晰了; 但是出现了一些新问题。

使用Python解释器时,没有编译发生? 如果是的话,什么时候? 例如,如果您只是在命令行键入代码并且每次进入回车时它都会运行,那么编译器何时有机会完成其工作?

同样在上面的问题链接中,@ delnan给出了一个非常广泛的编译器定义

A compiler is, more generally, a program that converts a program in
one programming language into a program in another programming
language...JIT compilers compile to native machine code at runtime

我想我的问题是:解释器和自动编译器之间有什么区别? 要稍微改进一下这个问题,如果编译Python,为什么不一直编译到机器代码(或汇编,因为我知道编写能够生成纯机器代码的编译器很困难)?


也许最好忘记语义,并尝试了解Cpython实际上在做什么。当您调用Cpython二进制文件时,它会执行许多操作。一般来说,您可以期望它将您编写的代码转换为字节码指令序列。这是人们有时会参考python代码的"编译"阶段。这些是一种更紧凑,更有效的方式来告诉解释器除了手写代码之外还要做什么。通常,python会缓存这些文件以便在.pyc文件中重用(只有在关联的.py文件较新时才重新生成)。您可以将python字节码视为python虚拟机可以运行的指令集 - 在很多方面,它与您获得的Java并不完全不同。当人们谈论编译语言(例如C)时,编译器的工作就是将代码转换为一组直接在计算机硬件上运行的指令。像Cpython和Java这样的语言具有额外的间接级别(例如虚拟机)。虚拟机直接在计算机的硬件上运行,负责解释特定于域的语言。

与标准的"编译"语言(例如CFortran)相比,这个阶段非常轻量级 - 而python并没有对"传统"编译器进行大量检查(例如,类型检查)。它几乎只检查语法,并使用窥孔优化器进行一些非常简单的优化。