• Python运行过程简单介绍


    1.背景

    编译:代码编程生成可执行文件,可执行文件不跨平台和架构,一次编译多次运行
      狭义上的编译是指从源码到机器码的过程,编译器比如GCC,MSVC
      广义上的编译是从一种代码到另一种代码(中间代码)
    解释:无需编译直接执行,但是解释器不跨架构和平台

    2.过程

    在这里插入图片描述

    1.编译

      虽然Python是一种解释性的语言,但实际上是先将Python代码编译成字节码(byte code),然后再执行,编译和解释执行都是使用CPython。编译过程与C语言的编译过程比较类似:

    1. 将Python源码分割为Token流
    2. 生成树形结构的Parser Tree
    3. 将Parse Tree转换为AST(抽象语法树,Abstract Syntax Tree)
    4. 构建符号表
    5. 根据AST和符号表生成code object

      每一个函数有一个code object,保存了函数的很多信息,其中co_code字段中保存了虚拟机指令的二进制表示(即byte code),将code object写入二进制文件(即.pyc文件)。

      程序运行时,code object保存再内存的PyCodeObject对象中,当程序运行结束时,将code object写入到.pyc文件中,下一次运行相同的程序时,Python会根据.pyc文件中的code object直接建立内存中的PyCodeObject对象,无需重新编译。

    2.解释执行

    (1). code object

      code object中byte code是二进制表示,反编译后可阅读,比如
    在这里插入图片描述

      include/opcode.h中共有121个opcode,CPython解释器中有一个很大的循环,不停读入opcode执行对应的指令,对应的指令使用C实现,比如
    在这里插入图片描述

    (2). frame

      在源代码编译成PyCodeObject对象后,就有虚拟机负责剩下的运行,虚拟机会从PyCodeObject中读取byte code(Python虚拟机指令,不是CPU指令),并在当前上下文中执行,但是PyCodeObject中不包含程序执行时所需的动态信息(上下文信息),程序运行的动态信息包含在frame中。

      每次调用函数或者刚开始运行Python时,会建立一个新的frame(可以这么理解,但是CPython存在优化,比如惰性对象),并在这个frame环境下一条一条运行byte code,每一条byte code有相应的C语言代码执行。frame是一个栈结构,但是实现是用链表实现的,该frame记录了返回地址和pc值等关键值。

     
     

    参考资料:

    编译器和解释器的区别
    深入理解Python虚拟机
    Python Internal
    CPython Internals
    码农高天:不基础的python基础

  • 相关阅读:
    浅析linux内核网络协议栈--linux bridge
    做软件测试三年,薪资不到20K,今天,我提出了辞职…
    粗糙集知识约简的python代码
    kafka安装与相关配置详解
    Jetpack Compose干货,如何让Compose Dialog从屏幕任意方向进入
    Ubuntu 安装keepalived
    Mysql的逻辑架构、存储引擎
    【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法
    揭晓:一条SQL语句的执行过程是怎么样的?
    嵌入式Qt-简易网络监控摄像头
  • 原文地址:https://blog.csdn.net/weixin_44343319/article/details/126204214