CPython是如何实现的?

Som*_*one 5 python cpython

所以我最近看到了对 Python 解释器和编译器(特别是 CPython)的解释。

如果我错了,请纠正我。我只是想确保我理解这些具体概念。

那么 CPython 既被编译(为字节码),又被解释(在 PVM 中)?PVM 到底是做什么的?它是否逐行读取字节码,并将每一行转换为可以在特定计算机上执行的二进制指令?这是否意味着基于 Intel 处理器的计算机需要与基于 AMD 的计算机不同的 PVM?

For*_*Bru 5

  1. 是的,CPython 被编译为字节码,然后由虚拟机执行。
  2. 虚拟机一条一条地执行指令。它是用 C 语言编写的(但您可以用其他语言编写),看起来像一个巨大的if/else语句,例如“如果当前指令是这个,则执行此操作;如果指令是这个,则执行另一件事”,等等。指令不会转换为二进制 - 这就是它被称为解释器的原因。
    1. 您可以在此处找到说明列表:https ://docs.python.org/3.10/library/dis.html#python-bytecode-instructions
    2. VM的实现可以在这里找到:https://github.com/python/cpython/blob/f71a69aa9209cf67cc1060051b147d6afa379bba/Python/ceval.c#L1718
  3. 字节码没有“行”的概念:它只是字节流。解释器可以一次读取一个字节,并使用另一条if/else语句来决定它正在查看什么指令。例如:
    curr_byte = read_byte()
    if curr_byte == 0x00:
       # Parse instruction with no arguments
       curr_instruction = DO_THING_A;
       args = NULL;
    elif curr_byte == 0x01:
       another_byte = read_byte()
       if another_byte == 0x00:
          # Parse a two-byte instruction
          curr_instruction = DO_THING_B;
          args = NULL;
       else:
          # Parse a one-byte instruction
          # with one argument
          curr_instruction = DO_THING_C;
          args = another_byte >> 1; # or whatever
    elif curr_byte == ...:
       ... # go on and on and on
    
    Run Code Online (Sandbox Code Playgroud)
  4. 字节码的全部要点是它可以由几乎任何硬件上的另一个程序(解释器或虚拟机)执行。例如,为了让 CPython 在新硬件上运行,您需要一个用于该硬件的 C 工具链(编译器、链接器、汇编器等)以及 Python 可以调用的一堆函数来执行低级操作(分配内存、输出文本,进行网络等)。完成后,编写可以执行字节码的 C 代码 - 就是这样。