一、编译过程概述

  当我们执行Python代码的时候,在Python解释器用四个过程“拆解”我们的代码,最终被CPU执行返回给用户。

  首先当用户键入代码交给Python处理的时候会先进行词法分析,例如用户键入关键字或者当输入关键字有误时,都会被词法分析所触发,不正确的代码将不会被执行。

  下一步Python会进行语法分析,例如当"for i in test:"中,test后面的冒号如果被写为其他符号,代码依旧不会被执行。

  下面进入最关键的过程,在执行Python前,Python会生成.pyc文件,这个文件就是字节码,如果我们不小心修改了字节码,Python下次重新编译该程序时会和其上次生成的字节码文件进行比较,如果不匹配则会将被修改过的字节码文件进行覆盖,以确保每次编译后字节码的准确性。

  那么什么是字节码?字节码在Python虚拟机程序里对应的是PyCodeObject对象。.pyc文件是字节码在磁盘上的表现形式。简单来说就是在编译代码的过程中,首先会将代码中的函数、类等对象分类处理,然后生成字节码文件。有了字节码文件,CPU可以直接识别字节码文件进行处理,接着Python就可执行了。

二、过程图解

三、编译字节码

  Python中有一个内置函数compile(),可以将源文件编译成codeobject,首先看这个函数的说明:

  compile(...) compile(source, filename, mode[, flags[, dont_inherit]]) -> code object

  参数1:源文件的内容字符串

  参数2:源文件名称

  参数3:exec-编译module,single-编译一个声明,eval-编译一个表达式 一般使用前三个参数就够了

  使用示例:

#src_file.py
#some function
def f(d=0):
c=1
print "hello"
a=9
b=8
f() >>> a=open('src_file.py','r').read() #命令行模式中打开源文件进行编译
>>> co=compile(a,'src_file','exec')
>>> type(co)
<type 'code'> #编译出了codeobject对象

四、codeobject对象的属性

  codeobject有哪些变量,接上节的内容分析一下:

>>> print co.co_names    #所有的符号名称
('f', 'a', 'b') >>> print co.co_name #模块名、函数名、类名
<module> >>> print co.co_consts #常量集合、函数f和两个int常量a,b,d
(0, <code object f at 0xb7273b18, file "src_file", line 2>, 9, 8, None) >>> print co.co_consts[1].co_varnames #可以看到f函数也是一个codeobject,打印f中的局部变量
('c',) >>> print co.co_code #字节码指令
dZdZdZedS >>> print co.co_consts[1].co_firstlineno #代码块在文件中的起始行号
2 >>> print co.co_stacksize #代码栈大小
2 >>> print co.co_filename #文件名
src_file #模块名、函数名、类名

  codeobject的co_code代表了字节码,这个字节码有什么含义?我们可以使用dis模块进行python的反编译:

import dis
dis.dis(co)
>>> output
2 0 LOAD_CONST 0 (0)
3 LOAD_CONST 1 (<code object f at 0xb7273b18, file "src_file", line 2>)
6 MAKE_FUNCTION 1
9 STORE_NAME 0 (f)
5 12 LOAD_CONST 2 (9)
15 STORE_NAME 1 (a) 6 18 LOAD_CONST 3 (8)
21 STORE_NAME 2 (b) 7 24 LOAD_NAME 0 (f)
27 CALL_FUNCTION 0
30 POP_TOP
31 LOAD_CONST 4 (None)
34 RETURN_VALUE

  从反编译的结果来看,python字节码其实是模仿的x86的汇编,将代码编译成一条一条的指令交给一个虚拟的cpu去执行。

  • 第一列:行号
  • 第二列:指令在代码块中的偏移量
  • 第三列:指令
  • 第四列:操作数
  • 第五列:操作数说明

Python内部执行过程的更多相关文章

  1. 【原创】控制perl和python脚本执行过程中脚本文件是否关闭的方法

    引子 跟踪perl和python脚本对文件的访问,实际过程中,perl和python解析器在解析完脚本后,直接关闭了 脚本文件,在进程中查询不到是访问文件的脚本文件名称. shell.perl和pyt ...

  2. CLRMonitor - 跟踪CLR内部执行过程工具

    CLRMonitor v1.0.1511.13 点击此处下载 软件介绍:这款软件主要用于跟踪CLR内部执行过程,定位当前程序执行的命名空间以及方法名等信息.可以迅速找到被跟踪程序的当前执行方法名.本软 ...

  3. .pyc是个什么 python的执行过程

    1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存在.如果是解释型语言, ...

  4. 当程序执行一条查询语句时,MySQL内部到底发生了什么? (说一下 MySQL 执行一条查询语句的内部执行过程?

    先来个最基本的总结阐述,希望各位小伙伴认真的读一下,哈哈: 1)客户端(运行程序)先通过连接器连接到MySql服务器. 2)连接器通过数据库权限身份验证后,会先查询数据库缓存是否存在(之前执行过相同条 ...

  5. android模拟器(genymotion)+appium+python 框架执行过程中问题解答

    1.case运行过程中中文输入不进去? 答:注意事项 1)需要修改系统编码为utf-8,才能解决中文输入问题,case执行入口文件添加代码如下: import sys reload(sys) sys. ...

  6. Struts2内部执行过程

    首先是Struts2的流程图. 一.当有一个请求的时候.执行以下流程. 1 客户端初始化一个指向Servlet容器的请求: 2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做Act ...

  7. mysql系列二、mysql内部执行过程

    向MySQL发送一个请求的时候,MySQL到底做了什么 客户端发送一条查询给服务器. 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器端进行SQL解析.预 ...

  8. python的执行过程

    1,解释器找到代码文件 2,将代码字符串按照文件头或者解释器默认的编码格式加载待内存,转为unicode格式 3,将代码字符串按照语法规则解释 4,转为二进制语言 5,进行执行

  9. 看看PHP迭代器的内部执行过程

    class myIterator implements Iterator { private $position = 0; private $array = array( "first_el ...

随机推荐

  1. lab 颜色模式的生理原因 黄色, 洋红色 刺眼。 绿色,蓝色,不刺眼。

    hsb 颜色模式理解了. lab 颜色模式,都说是生理原因.没说是啥生理原因. 猜测:黄色, 洋红色 刺眼.   绿色,蓝色,不刺眼. https://blog.csdn.net/self_mind/ ...

  2. 【WPF】非UI线程操作UI

    在线程中添加下面两行,把操作UI的命令放到一个新函数中 Action 起个名 = new Action(操作UI的函数名);要操作的控件名.Dispatcher.BeginInvoke(起个名);

  3. python多进程——进程间通信

    (一)进程锁 抢票的例子: # -*- coding:utf-8 -*- from multiprocessing import Process, Lock import time import js ...

  4. 开发单体web shop] 6. 商品分类和轮播广告展示

    目录 商品分类&轮播广告 商品分类|ProductCategory 需求分析 开发梳理 编码实现 轮播广告|SlideAD 需求分析 开发梳理 编码实现 福利讲解 源码下载 下节预告 商品分类 ...

  5. React 克隆组件 -- React.cloneElement(可以用来修改子组件属性值,复制子组件,添加子组件)

    项目要求实现按钮级权限,简单来说就是需要通过后台数据绑定来控制前端页面哪些操作按钮需要渲染,哪些操作按钮不需要渲染, 大体的方案是: 在原有的按钮标签外再套一层按钮权限控制标签,然后每个具体的按钮对照 ...

  6. MATLAB实现OTSU

    目录 1.OTSU算法原理简述: 2.MATLAB实现代码 @ 1.OTSU算法原理简述: 最大类间方差是由日本学者大津(Nobuyuki Otsu)于1979年提出,是一种自适应的阈值确定方法.算法 ...

  7. Django-ORM之ForeignKey的使用-多对一关系

    ForeignKey使用俩表示两张表多对一关系的外键,外键字段要定义在多属性的表中. 定义外键时,to的表可以直接写类名,但是需要注意类的定义顺序:也可以写字符串式的类名,这样就可以忽略class类的 ...

  8. 对scrapy进行单元测试 -- 使用betamax

    使用betamax进行单元测试 爬虫代码 测试代码 对于scrapy的单元测试,官方文档并没有提到,只是说有一个Contract功能.但是相信我,这个东西真的不好用,甚至scrapy的作者在一个iss ...

  9. 解决incorrect 'only available in ES6' warning (W119) with options `moz: true, esversion: 6` 报错问题

    很多同学在新建vue项目时,会遇到 incorrect 'only available in ES6' warning (W119) with options `moz: true, esversio ...

  10. ubuntu 16.04 server 扩容(LVM)磁盘

    因为发现我的本地server出现磁盘满了的情况 所以进行lvm的扩容 1 查看磁盘情况 df -h 原本发现 /dev/mapper/ubuntu1604--vg-root 这个磁盘满了 所以要进行扩 ...