詳解python位元組碼

2022-10-03 15:27:11 字數 2020 閱讀 5352

python對不可變序列進行重複拼接操作效率會很低,因為每次都會生成乙個新的物件,直譯器需要把原來物件中的元素先複製到新的物件裡,然後再追加新的元素。

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

通過位元組碼研究一下這個過程。

>>> s_code = 'a += "b"'

>>> c = compile(s_code, '', 'exec')

>>> c.co_code

b'e\x00\x00d\x00\x007z\x00\x00d\x01\x00s'

>>> c.co_names

('a',)

>>> c.co_consts

('b', none)

得到的位元組碼是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,也就是htfquoc二進位制的0000 0000。

至此,所有位元組都可被表示。

回到開始的**。為了顯示方便,將b'e\x00\x00d\x00\x007程式設計客棧z\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_name

0000:引數,將co_names[0]的值,即a的值,壓入棧

64:3,load_const

0000:引數,將co_consts[0],即'b',壓入棧

37:6,inplace_add,tos = tos1 + tos

5a:7,store_name

0000:引數,co_names[0]=tos,即將棧頂賦值給a

64:10,load_const

0100:引數

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')

6www.cppcns.com inplace

7 store_name 0 (a)

10 load_const 1 (none)

13 rhtfquoceturn_value

完整**:

s_code = 'a += "b"'

c = compile(s_code, '', 'exec')

c.co_code

c.co_names

c.co_consts

c.co_code.hex()

import dis

dis.dis(s_code)

非常失敗,對比了string和tuple的賦值位元組碼,並沒有看出string的優化…

python位元組碼 Python位元組碼簡介

python位元組碼 如果您曾經編寫過python,或者甚至只是使用過python,那麼您可能已經習慣了檢視python源 檔案。它們的名稱以.py結尾。而且您可能還看到了另一種型別的檔案,其名稱以.pyc結尾,並且您可能已經聽說它們是python的 位元組碼 檔案。這些在python 3上很難看到...

python 位元組碼

python位元組碼 hello.py usr bin env python coding utf 8 import m 呼叫m裡的方法 執行之後會生成乙個m.pyc檔案 如果將m.py檔案刪除,只留hello.py和m.pyc檔案,同樣能執行出效果 對於hello.py m.py m.pyc 三個...

python 位元組碼 優化 位元組碼優化

python是一種動態語言。這意味著您在編寫 方面有很大的自由度。由於python公開了大量的自省 順便說一句,這非常有用 許多優化根本無法執行。例如,在第乙個示例中,python無法知道呼叫它時list是什麼資料型別。我可以建立乙個非常奇怪的類 class crazylist object pri...