python程序执行原理
Python程序的执行原理 1. 过程概述
Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后解释器一条一条执行字节码指令,从而完成程序的执行。 1.1python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后解释器会从编译得到的PyCodeObject对象中一条一条执行字节码指令,
并在当前的上下文环境中执行这条字节码指令,从而完成程序的执行。Python解释器实际上是在模拟操作中执行文件的过程。PyCodeObject对象
中包含了字节码指令以及程序的所有静态信息,但没有包含程序运行时的动态信息——执行环境(PyFrameObject) 2. 字节码
字节码在python解释器程序里对应的是PyCodeObject对象
.pyc文件是字节码在磁盘上的表现形式 2.1从整体上看:OS中执行程序离不开两个概念:进程和线程。python中模拟了这两个概念,模拟进程和线程的分别是PyInterpreterState和
PyTreadState。即:每个PyThreadState都对应着一个帧栈,python解释器在多个线程上切换。当python解释器开始执行时,它会先进行一
些初始化操作,最后进入PyEval_EvalFramEx函数,它的作用是不断读取编译好的字节码,并一条一条执行,类似CPU执行指令的过程。函数内部
主要是一个switch结构,根据字节码的不同执行不同的代码。 3. .pyc文件
PyCodeObject对象的创建时机是模块加载的时候,及import
Python test.py会对test.py进行编译成字节码并解释执行,但是不会生成test.pyc
如果test.py加载了其他模块,如import urlib2, Python会对urlib2.py进行编译成字节码,生成urlib2.pyc,然后对字节码进行解释
如果想生成test.pyc,我们可以使用Python内置模块py_compile来编译。
加载模块时,如果同时存在.py和pyc,Python会尝试使用.pyc,如果.pyc的编译时间早于.py的修改时间,则重新编译.py并更新.pyc。 4. PyCodeObject
Python代码的编译结果就是PyCodeObject对象 typedef struct {
PyObject_HEAD
int co_argcount; /* 位置参数个数 */
int co_nlocals; /* 局部变量个数 */
int co_stacksize; /* 栈大小 */
int co_flags;
PyObject *co_code; /* 字节码指令序列 */
PyObject *co_consts; /* 所有常量集合 */
PyObject *co_names; /* 所有符号名称集合 */
PyObject *co_varnames; /* 局部变量名称集合 */
PyObject *co_freevars; /* 闭包用的的变量名集合 */
PyObject *co_cellvars; /* 内部嵌套函数引用的变量名集合 */
/* The rest doesn’t count for hash/cmp */
PyObject *co_filename; /* 代码所在文件名 */
PyObject *co_name; /* 模块名|函数名|类名 */
int co_firstlineno; /* 代码块在文件中的起始行号 */
PyObject *co_lnotab; /* 字节码指令和行号的对应关系 */
void *co_zombieframe; /* for optimization only (see frameobject.c) */
} PyCodeObject; 5. .pyc文件格式
加载模块时,模块对应的PyCodeObject对象被写入.pyc文件 6.分析字节码 6.1解析PyCodeObject
Python提供了内置函数compile可以编译python代码和查看PyCodeObject对象 6.2指令序列co_code的格式 opcode oparg opcode opcode oparg …
1 byte 2 bytes 1 byte 1 byte 2 bytes
Python内置的dis模块可以解析co_code 7. 执行字节码
Python解释器的原理就是模拟可执行程序再X86机器上的运行,X86的运行时栈帧如下图
Python解释器的原理就是模拟上述行为。当发生函数调用时,创建新的栈帧,对应Python的实现就是PyFrameObject对象。
PyFrameObject对象创建程序运行时的动态信息,即执行环境 7.1 PyFrameObject typedef struct _frame{
PyObject_VAR_HEAD //"运行时栈"的大小是不确定的
struct _frame *f_back; //执行环境链上的前一个frame,很多个PyFrameObject连接起来形成执行环境链表
PyCodeObject *f_code; //PyCodeObject 对象,这个frame就是这个PyCodeObject对象的上下文环境
PyObject *f_builtins; //builtin名字空间
PyObject *f_globals; //global名字空间
PyObject *f_locals; //local名字空间
PyObject **f_valuestack; //"运行时栈"的栈底位置
PyObject **f_stacktop; //"运行时栈"的栈顶位置
//...
int f_lasti; //上一条字节码指令在f_code中的偏移位置
int f_lineno; //当前字节码对应的源代码行
//... //动态内存,维护(局部变量+cell对象集合+free对象集合+运行时栈)所需要的空间
PyObject *f_localsplus[1];
} PyFrameObject; 每一个 PyFrameObject对象都维护了一个 PyCodeObject对象,这表明每一个 PyFrameObject中的动态内存空间对象都和源代码中的一段Code相对应。
python程序执行原理的更多相关文章
- python笔记:#006#程序执行原理
程序执行原理(科普) 目标 计算机中的 三大件 程序执行的原理 程序的作用 01. 计算机中的三大件 计算机中包含有较多的硬件,但是一个程序要运行,有 三个 核心的硬件,分别是: CPU 中央处理器, ...
- python解释执行原理(转载)
Python解释执行原理 转自:http://l62s.iteye.com/blog/1481421 这里的解释执行是相对于编译执行而言的.我们都知道,使用C/C++之类的编译性语言编写的程序,是需要 ...
- 【跟我一起学Python吧】Python解释执行原理
这里的解释执行是相对于编译执行而言的.我们都知道,使用C/C++之类的编译性语言编写的程序,是需要从源文件转换成计算机使用的机器语言,经过链接器链接之后形成了二进制的可执行文件.运行该程序的时候,就可 ...
- 【和我一起学python吧】Python解释执行原理
这里的解释执行是相对于编译执行而言的.我们都知道,使用C/C++之类的编译性语言编写的程序,是需要从源文件转换成计算机使用的机器语言,经过链接器链接之后形成了二进制的可执行文件.运行该程序的时候,就可 ...
- Python程序执行顺序
#示例代码基于py3.6 一直对Python程序的执行顺序有些疑惑,例如python程序是顺序执行的,那怎么还有main函数的出现呢? 在查阅了资料后,参见这里后,算是有点明白了: 1.python程 ...
- 关于提高python程序执行效率的思路和想法
相比编译型语言(C系列)python胜在简介的语法和优雅的动态编程体验,但是在执行效率上,python有解释性语言先天的劣势——执行效率较低,为了让编写出的程序获得更快的执行效率,开启此文章. pyt ...
- Python程序执行时的不同电脑路径不同问题
原因:因代码转移时项目路径发生了变化,导致解释器无法找到对应路径,是的程序无法正常执行 需求: 1.我希望代码能在不同的电脑下,不必修改源代码就能正常执行(所需模块已安装的前提下) 2.我希望代码在命 ...
- os.popen('python hello_out.py')中Python程序执行时默认的当前路径为MS-DOS CMD的默认路径
>>> import os >>> os.getcwd() 'D:\\pythonCode\\pp4e' >>> os.chdir('Stream ...
- Python程序打包工具PyInstaller
Python程序执行 py文件:直接提供源码,需要使用者自行安装Python并且安装依赖的各种库 pyc文件:pyc文件是Python解释器可以识别的二进制码,是跨平台的,需要使用者安装相应版本的Py ...
随机推荐
- python课程设计笔记(三)turtle绘图库(海龟库)
实例:绘制一条蟒蛇 #turtle:绘图库(海龟库) import turtle turtle.setup(650,350,200,200) turtle.penup() turtle.fd(-250 ...
- js+css模仿打字效果
1.效果 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %> ...
- (转)一个vue路由参数传递的注意点
首先我的路由的定义 { path: '/b', name: 'B', component: resolve => require(['../pages/B.vue'], resolve) } 我 ...
- Android Toolbar使用及Fragment中的Toolbar处理
Toolbar作为ActionBar使用介绍 本文介绍了在Android中将Toolbar作为ActionBar使用的方法.并且介绍了在Fragment和嵌套Fragment中使用Toolbar作为A ...
- Paint、Canvas.1
Canvas 方法详解 1:translate(float dx, float dy) /**** 移动canvas的原点到(dx,dy),默认为(0,0) */ public void transl ...
- django 安装运行
pip install django pip list 查看版本 python -m django --version 新建django django-admin startproject mysit ...
- 配置notepad++编程环境
1. 到 https://sourceforge.net/projects/mingw-w64/files/ 下载MinGW64,解压并移动到C盘根目录 2. 将 C:\MinGW64\bin 加入系 ...
- Django02 Django基础知识
一.内容回顾 1.web应用程序 2.HTTP协议 a.http协议特性 b.http请求格式 c.http响应格式 3.wsgiref模块 4.Django下载与简单应用 a.Django简介(MT ...
- 10件5G能实现,但4G不能做的事情
10件5G能实现,但4G不能做的事情 从三星Galaxy S10 5G手机到OnePlus 7 Pro 5G手机以及更高版本,首批5G手机现已上市.5G网络时代的开启是从小范围内,如果你居住在可以使用 ...
- jemeter安装步骤
1.jmeter下载地址:http://jmeter.apache.org/download_jmeter.cgi 2.在安装jmeter之前首先要安装jdk1.8以上版本,朋友们,千万不要忘了 jd ...