Python學習之pyc檔案與code對象

來源:互聯網
上載者:User

標籤:

本文和大家分享的主要是python中的pyc檔案與code對象相關內容,一起來看看吧,希望對大家學習python有所協助。 python對來源程式編譯結果是產生一個 .pyc 檔案. python對 .py 檔案的編譯結果是位元組碼, 為了能複用而不需要重新編譯才有了寫成 .pyc 檔案. 對於解譯器來說 PyCodeObject 對象才是真正編譯結果, pyc檔案只是這個對象在硬碟上的表現形式. PyCodeObject [code.h]typedef struct { PyObject_HEAD int co_argcount;        /* #arguments, except *args */ int co_kwonlyargcount;  /* #keyword only arguments */ int co_nlocals;     /* #local variables */ int co_stacksize;       /* #entries needed for evaluation stack */ int co_flags;       /* CO_..., see below */ int co_firstlineno;   /* first source line number */ PyObject *co_code;      /* instruction opcodes */ PyObject *co_consts;    /* list (constants used) */ PyObject *co_names;     /* list of strings (names used) */ PyObject *co_varnames;  /* tuple of strings (local variable names) */ PyObject *co_freevars;  /* tuple of strings (free variable names) */ PyObject *co_cellvars;      /* tuple of strings (cell variable names) */ void *co_extra; } PyCodeObject; 編譯器在對原始碼進行編譯的時候, 每一個 Code Block 會建立一個 PyCodeObject 對象與這個程式碼片段相對應. 程式碼片段的範圍可大可小. 可以是整個py檔案, 可以是class, 可以是函數. 訪問PyCodeObject對象 在python中, 有與c一級的對PyCodeObject簡單封裝, code對象, 可以訪問到PyCodeObject的各個域. >>> source = open(’db.py’).read()>>> co = compile(source, ’db.py’, ’exec’)>>> type(co) <class ’code’>>>> co.co_names (’pymysql’, ’config’, ’threading’, ’RLock’, ’Lock’, ’create_table_template’, ’ob ject’, ’Model’, ’str’, ’m’) 寫入檔案 PyMarshal_WriteObjectToFile 向pyc檔案寫入資料主要是這幾個, 有刪減: [marshal.c] typedef struct { FILE *fp; int depth; PyObject *str; char *ptr; char *end; char *buf; _Py_hashtable_t *hashtable; int version; } WFILE; #define w_byte(c, p) do {                               if ((p)->ptr != (p)->end || w_reserve((p), 1))   *(p)->ptr++ = (c);                           } while(0) static void w_flush(WFILE *p) { assert(p->fp != NULL); fwrite(p->buf, 1, p->ptr - p->buf, p->fp); p->ptr = p->buf; } 這是檔案寫入定義的基本結構, fp指向最後要寫入的檔案, w_byte(c, p) 則是一個簡單的封裝, 以位元組為單位的複製到p->ptr先行區中. w_flush(WFILE *p) 則是將緩衝區 p->buf 寫到檔案中.p->ptr也就是準備寫到檔案中的增量部分. static void w_long(long x, WFILE *p) { w_byte((char)( x      & 0xff), p); w_byte((char)((x>> 8) & 0xff), p); w_byte((char)((x>>16) & 0xff), p); w_byte((char)((x>>24) & 0xff), p); } static void w_string(const char *s, Py_ssize_t n, WFILE *p) { Py_ssize_t m; if (!n || p->ptr == NULL) return; m = p->end - p->ptr; if (p->fp != NULL) { if (n <= m) { memcpy(p->ptr, s, n); p->ptr += n; } else { w_flush(p); fwrite(s, 1, n, p->fp); } } else { if (n <= m || w_reserve(p, n - m)) { memcpy(p->ptr, s, n); p->ptr += n; } } } 如在調用 PyMarshal_WriteLongToFile 時, 會調用 w_long , 資料將會一個位元組位元組的寫入到檔案中. 而調用PyMarshal_WriteObjectToFile 也會調用 w_object , 這個函數比較長,就不列出來了. 為了區分寫入的類型, 在寫入檔案前會做一個動作,就是先將待寫入的物件類型寫進去: [marshal.c] #define TYPE_NULL               ’0’ #define TYPE_NONE               ’N’ #define TYPE_FALSE              ’F’ #define TYPE_TRUE               ’T’ #define TYPE_STOPITER           ’S’ #define W_TYPE(t, p) do { w_byte((t) | flag, (p)); } while(0) 這個物件類型的標識對讀取pyc檔案至關重要, 因為對象寫入pyc檔案後, 所有資料都變成位元組流, 類型資訊丟失. 有了這個標識, 當讀取這樣的標識時, 則預示著上一個對象結束, 新的對象開始, 也能知道新對象是什麼類型的. 內部也有機制處理共用對象, 減少位元組碼中冗餘資訊. 共用類型的屬於 TYPE_INTERNED . 載入pyc檔案 PyMarshal_ReadObjectFromFile 看一下載入pyc檔案的過程, 讓pyc檔案理解更加深刻: PyObject * PyMarshal_ReadObjectFromFile(FILE *fp) { RFILE rf; PyObject *result; rf.fp = fp; rf.readable = NULL; rf.current_filename = NULL; rf.depth = 0; rf.ptr = rf.end = NULL; rf.buf = NULL; rf.refs = PyList_New(0); if (rf.refs == NULL) return NULL; result = r_object(&rf); Py_DECREF(rf.refs); if (rf.buf != NULL) PyMem_FREE(rf.buf); return result; } 從 r_object 開始就開始從pyc檔案中讀入資料, 並建立PyCodeObject對象, 這個 r_object 是對 w_object 的逆運算. 當讀到 TYPE_INTERNED 後, 會將其後面的字串讀入, 將這個字串進行intern操作.來源:棲遲於一丘

Python學習之pyc檔案與code對象

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.