文档章节

zg手册 之 python2.7.7源码分析(4)-- pyc字节码文件

 东昕
发布于 2014/09/20 22:54
字数 670
阅读 126
收藏 4

什么是字节码

  1. python解释器在执行python脚本文件时,对文件中的python源代码进行编译,编译的结果就是byte code(字节码)

  2. python虚拟机执行编译好的字节码,完成程序的运行

  3. python会为导入的模块创建字节码文件


字节码文件的创建过程

  1. 当a.py依赖b.py时,如在a.py中import b

  2. python先检查是否有b.pyc文件(字节码文件),如果有,并且修改时间比b.py晚,就直接调用b.pyc

  3. 否则编译b.py生成b.pyc,然后加载新生成的字节码文件


字节码对象

  1. 每个py文件会包含许多代码块(Code Block)

  2. 每个代码块(Code Block)会编译创建一个字节码对象(PyCodeObject)

  3. PyCodeObject 对象本身是嵌套的,根据代码块的结构嵌套

  4. 子 PyCodeObject 对象保存在父对象的 co_consts 变量中


代码块 Code Block

# 整个文件是一个代码块 1

# 代码块 2
class TestA(object):
    pass

# 代码块 3
class TestB(object):
    pass

# 代码块 4
def show():
    print 'show ...'

a = TestA()show()


字节码对象的结构

/* 字节码对象 */
typedef struct {
    PyObject_HEAD
    int co_argcount;        /* Code Block 参数个数 */
    int co_nlocals;     /* 局部变量个数 */
    int co_stacksize;       /* 栈空间 */
    int co_flags;       /* CO_..., see below */
    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;  /* py文件路径 */
    PyObject *co_name;      /* Code block 的函数名或类名 */
    int co_firstlineno;     /* Code block 起始行 */
    PyObject *co_lnotab;    /* 字节码指令与源代码的对应关系 */
    void *co_zombieframe;     /* for optimization only (see frameobject.c) */
    PyObject *co_weakreflist;   /* to support weakrefs to code objects */
} PyCodeObject;


字节码文件的内部实现

字节码对象序列化到硬盘的结果,就是字节码文件。这个过程是一个递归写入的过程。

static void w_object(PyObject *v, WFILE *p){
    Py_ssize_t i, n;
    p->depth++;

    /* ... */
    else if (PyCode_Check(v)) {
        PyCodeObject *co = (PyCodeObject *)v;
        w_byte(TYPE_CODE, p);
        w_long(co->co_argcount, p);
        w_long(co->co_nlocals, p);
        w_long(co->co_stacksize, p);
        w_long(co->co_flags, p);
        w_object(co->co_code, p);
        w_object(co->co_consts, p);
        w_object(co->co_names, p);
        w_object(co->co_varnames, p);
        w_object(co->co_freevars, p);
        w_object(co->co_cellvars, p);
        w_object(co->co_filename, p);
        w_object(co->co_name, p);
        w_long(co->co_firstlineno, p);
        w_object(co->co_lnotab, p);
    }
    /* ... */
}


反序列化执行字节码文件

字节码文件在反序列化时创建字节码对象的结构,虚拟机在执行的时候根据字节码对象执行程序功能。


原文链接:zg手册 之 python2.7.7源码分析(4)-- pyc字节码文件

© 著作权归作者所有

粉丝 12
博文 22
码字总数 16965
作品 0
浦东
架构师
私信 提问
zg手册 之 python2.7.7源码分析(5)-- python的作用域和名空间

在 python 中, module,作用域,名空间这几个概念与虚拟机的运行机制有紧密的联系, 这里先了解 module,作用域,和名空间,为后面分析虚拟机的运行做准备。 module 在python中一个文件对应...

东昕
2014/10/26
126
1
zg手册 之 python2.7.7源码分析(1)-- python中的对象

源代码主要目录结构 Demo: python 的示例程序 Doc: 文档 Grammar: 用BNF的语法定义了Python的全部语法,提供给解析器使用 Include: 头文件,在用c/c++编写扩展模块时使用 Lib: Python自...

东昕
2014/07/08
157
0
云计算Python自动化:python文件类型讲解

Python的文件类型主要分为3种:源代码(source file)、字节码(byte-code file)、优化的字节码(optimized file)。这些代码都可以直接运行,不需要编译或者连接。这正是Python语言的特性,...

长沙千锋
2018/05/16
0
0
zg手册 之 python2.7.7源码分析(3)-- list 对象和 dict 对象

list 对象 list 对象的定义 list对象内部是使用数组实现,在数组中存储的是指针,指向要保存的对象。 allocated是list中数组的大小,ob_size是当前已经使用的数组大小。 typedef struct { /...

东昕
2014/08/26
128
0
看书 Python 源码分析笔记 (十一) 模块加载机制

第14章 Python 模块的动态加载机制 现实程序通常由多个模块构成, 模块之间存在引用和交互. 本章剖析如何加载模块, 引用另一模块中的功能. import 命令 import sys 被编译后的字节指令示例: 这...

刘军兴
2015/12/28
109
0

没有更多内容

加载失败,请刷新页面

加载更多

浅谈梯子游戏三门打法技巧走势攻略教程(学会稳稳上岸)

摘要:那么下面我就给大家总结一下技巧和玩法!一、玩梯子的前期准备:1,最重要是zi金准备,提前做好ben金准备能保证自己的zi金链不断,稳中求胜。2,其次是止sun底线,风险控制一定要懂得舍弃,买彩...

V_6696089
22分钟前
6
0
今天发布 需求登记表,不戴眼镜开发的成果

今天是不戴眼镜调理第八天 之前带五百度眼睛0.5 现在是做了三次调理,通常,成人比青少年要慢些 明天正式学习 调理技术 最近不怎么开电脑做开发,发现时间多了许多 虽然想把开发缓一阵子,但...

蒋志祥
30分钟前
2
0
Linux 之docker部署,走过的那些坑

初次使用docker, 多有不足,这里把坑一点点的记下来 概念篇 docker 是什么? 太多文字不同,书读的少, 不懂大大道理; 在我的理解, 它就是个沙箱环境; 在linux中 ,独立进程, 有着自己的小世界 使...

莫库什勒
44分钟前
5
0
vue class绑定 组件

本文转载于:专业的前端网站➬vue class绑定 组件 当在一个自定义组件上使用 class 属性时,这些类将被添加到该组件的根元素上面。这个元素上已经存在的类不会被覆盖。 例如,如果你声明了这个...

前端老手
今天
4
0
exist和in

exist和in select ..from table where exist (子查询) ; select ..from table where 字段 in (子查询) ; 如果主查询的数据集大,则使用In,效率高。 如果子查询的数据集大,则使用exist,效率高...

潦草的犀牛
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部