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基础

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值