zg手冊 之 python2.7.7源碼分析(4)-- pyc字節碼文件

什麼是字節碼

  1. python解釋器在執行python腳本文件時,對文件中的python源代碼進行編譯,編譯的結果就是byte code(字節碼)python

  2. python虛擬機執行編譯好的字節碼,完成程序的運行閉包

  3. python會爲導入的模塊建立字節碼文件python2.7


字節碼文件的建立過程

  1. 當a.py依賴b.py時,如在a.py中import b函數

  2. python先檢查是否有b.pyc文件(字節碼文件),若是有,而且修改時間比b.py晚,就直接調用b.pyc源碼分析

  3. 不然編譯b.py生成b.pyc,而後加載新生成的字節碼文件spa


字節碼對象

  1. 每一個py文件會包含許多代碼塊(Code Block)rest

  2. 每一個代碼塊(Code Block)會編譯建立一個字節碼對象(PyCodeObject)code

  3. PyCodeObject 對象自己是嵌套的,根據代碼塊的結構嵌套對象

  4. 子 PyCodeObject 對象保存在父對象的 co_consts 變量中blog


代碼塊 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字節碼文件

相關文章
相關標籤/搜索