国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

深入Python解釋器理解Python中的字節碼

2020-02-23 00:28:46
字體:
來源:轉載
供稿:網友

我最近在參與Python字節碼相關的工作,想與大家分享一些這方面的經驗。更準確的說,我正在參與2.6到2.7版本的CPython解釋器字節碼的工作。

Python是一門動態語言,在命令行工具下運行時,本質上執行了下面的步驟:

    當第一次執行到一段代碼時,這段代碼會被編譯(如,作為一個模塊加載,或者直接執行)。根據操作系統的不同,這一步生成后綴名是pyc或者pyo的二進制文件。     解釋器讀取二進制文件,并依次執行指令(opcodes)。

Python解釋器是基于棧的。要理解數據流向,我們需要知道每條指令的棧效應(如,操作碼和參數)。

探索Python二進制文件

得到一個二進制文件字節碼的最簡單方式,是對CodeType結構進行解碼:
 

import marshalfd = open('path/to/my.pyc', 'rb')magic = fd.read(4) # 魔術數,與python版本相關date = fd.read(4) # 編譯日期code_object = marshal.load(fd)fd.close()

code_object包含了一個CodeType對象,它代表被加載文件的整個模塊。為了查看這個模塊的類定義、方法等的所有嵌套編碼對象(編碼對象,原文為code object),我們需要遞歸地檢查CodeType的常量池。就像下面的代碼:
 

import types def inspect_code_object(co_obj, indent=''):print indent, "%s(lineno:%d)" % (co_obj.co_name, co_obj.co_firstlineno)for c in co_obj.co_consts:if isinstance(c, types.CodeType):inspect_code_object(c, indent + ' ') inspect_code_object(code_object) # 從第一個對象開始

這個案例中,我們打印出一顆編碼對象樹,每個編碼對象是其父對象的子節點。對下面的代碼:
 

class A:def __init__(self):passdef __repr__(self):return 'A()'a = A()print a

我們得到的樹形結果是:

<module>(lineno:2) A(lineno:2) __init__(lineno:3) __repr__(lineno:5)

為了測試,我們可以通過compile指令,編譯一個包含Python源碼的字符串,從而能夠得到一個編碼對象:
 

co_obj = compile(python_source_code, '<string>', 'exec')

要獲取更多關于編碼對象的信息,我們可以查閱Python文檔的co_* fields 部分。

初見字節碼

一旦我們得到了編碼對象,我們就可以開始對它進行拆解了(在co_code字段)。從字節碼中解析出它的含義:

? 解釋操作碼的含義 ? 提取任意參數

dis模塊的disassemble函數展示了是如何做到的。對我們前面例子,它輸出的結果是:

2 0 LOAD_CONST 0 ('A') 3 LOAD_CONST 3 (()) 6 LOAD_CONST 1 (<code object A at 0x42424242, file "<string>", line 2>) 9 MAKE_FUNCTION 0 12 CALL_FUNCTION 0 15 BUILD_CLASS 16 STORE_NAME 0 (A) 8 19 LOAD_NAME  0 (A) 22 CALL_FUNCTION 0 25 STORE_NAME 1 (a) 9 28 LOAD_NAME  1 (a) 31 PRINT_ITEM 32 PRINT_NEWLINE 33 LOAD_CONST 2 (None) 36 RETURN_VALUE            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新竹市| 怀宁县| 丹巴县| 庆城县| 邮箱| 中卫市| 三门峡市| 同江市| 福海县| 鹤峰县| 呼和浩特市| 商都县| 咸阳市| 交城县| 十堰市| 黄梅县| 噶尔县| 遵化市| 民权县| 东阳市| 五指山市| 乐昌市| 龙岩市| 定襄县| 山阳县| 永兴县| 涟水县| 措美县| 建德市| 南丰县| 砚山县| 德安县| 思茅市| 台东县| 察隅县| 沙坪坝区| 迁西县| 广州市| 泰州市| 柳江县| 玉田县|