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

首頁 > 編程 > Python > 正文

詳解python字節碼

2020-02-22 23:09:18
字體:
來源:轉載
供稿:網友

Python對不可變序列進行重復拼接操作效率會很低,因為每次都會生成一個新的對象,解釋器需要把原來對象中的元素先復制到新的對象里,然后再追加新的元素。

但是CPython對字符串操作進行了優化,因為對字符串做+=操作實在是太普遍了。因此,初始化str時會預留出額外的可擴展空間,從而進行增量操作的時候不會有復制再追加的這個步驟。

通過字節碼研究一下這個過程。

>>> s_code = 'a += "b"'>>> c = compile(s_code, '', 'exec')>>> c.co_codeb'e/x00/x00d/x00/x007Z/x00/x00d/x01/x00S'>>> c.co_names('a',)>>> c.co_consts('b', None)

得到的字節碼是Bytes類型的。這里穿插一些Bytes類型的知識。

Bytes類型

b'e/x00/x00d/x00/x007Z/x00/x00d/x01/x00S',b表示是Bytes類型。Bytes以二進制字節序列的形式記錄數據,每一個字符就代表一個字節(8位)。比如上面的e表示二進制0110 0101。部分ASCII碼對照表如下圖所示。

但是,不是所有的字節都是可顯示的,甚至有些字節無法對應到ASCII碼上(因為ASCII碼只定義了128個字符,而一個字節有256個)。比如0000 0000對應的ASCII是不可顯示的、0111 1111沒有對應的ASCII碼。

為了表示這些無法顯示的字節,就引入了/x符號,其表示后續的字符為16進制。如,/x00表示16進制的00,也就是二進制的0000 0000。

至此,所有字節都可被表示。

字節碼分析

回到開始的代碼。為了顯示方便,將b'e/x00/x00d/x00/x007Z/x00/x00d/x01/x00S'轉為16進制來顯示。

>>> c.co_code.hex()'650000640000375a000064010053'

通過opcode.opname函數可以得到操作碼所對應的操作指令

>>> import opcode>>> opcode.opname[0x65]'LOAD_NAME'

因此,完整的字節碼可以解釋為(TOS即top-of-stack,棧頂元素):

字節:位置,功能65:0,LOAD_NAME0000:參數,將co_names[0]的值,即a的值,壓入棧64:3,LOAD_CONST0000:參數,將co_consts[0],即'b',壓入棧37:6,INPLACE_ADD,TOS = TOS1 + TOS5a:7,STORE_NAME0000:參數,co_names[0]=TOS,即將棧頂賦值給a64:10,LOAD_CONST0100:參數53:13,RETURN_VALUE,Returns with TOS to the caller of the function

實際上借助dis函數可以直接獲得可讀的字節碼:

>>> import dis>>> dis.dis(s_code) 1      0 LOAD_NAME        0 (a)       3 LOAD_CONST        0 ('b')       6 INPLACE_ADD       7 STORE_NAME        0 (a)       10 LOAD_CONST        1 (None)       13 RETURN_VALUE

完整代碼:

s_code = 'a += "b"'c = compile(s_code, '', 'exec')c.co_codec.co_namesc.co_constsc.co_code.hex()import disdis.dis(s_code)            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 象州县| 慈利县| 水富县| 怀远县| 巴彦淖尔市| 岫岩| 陆丰市| 介休市| 德昌县| 兰西县| 沧州市| 信阳市| 容城县| 古田县| 吴忠市| 普定县| 随州市| 门头沟区| 平潭县| 保亭| 龙江县| 华池县| 穆棱市| 乌苏市| 久治县| 旺苍县| 电白县| 达州市| 西昌市| 揭西县| 贡嘎县| 高台县| 新宾| 庆城县| 肃南| 墨江| 宁夏| 称多县| 城步| 佛山市| 石渠县|