dis --- Python 字節(jié)碼反匯編器?
Source code: Lib/dis.py
dis 模塊通過(guò)反匯編支持CPython的 bytecode 分析。該模塊作為輸入的 CPython 字節(jié)碼在文件 Include/opcode.h 中定義,并由編譯器和解釋器使用。
CPython implementation detail: 字節(jié)碼是 CPython 解釋器的實(shí)現(xiàn)細(xì)節(jié)。不保證不會(huì)在Python版本之間添加、刪除或更改字節(jié)碼。不應(yīng)考慮將此模塊的跨 Python VM 或 Python 版本的使用。
在 3.6 版更改: 每條指令使用2個(gè)字節(jié)。以前字節(jié)數(shù)因指令而異。
示例:給出函數(shù) myfunc():
def myfunc(alist):
return len(alist)
可以使用以下命令顯示 myfunc() 的反匯編
>>> dis.dis(myfunc)
2 0 LOAD_GLOBAL 0 (len)
2 LOAD_FAST 0 (alist)
4 CALL_FUNCTION 1
6 RETURN_VALUE
("2" 是行號(hào))。
字節(jié)碼分析?
3.4 新版功能.
字節(jié)碼分析 API 允許將 Python 代碼片段包裝在 Bytecode 對(duì)象中,以便輕松訪問(wèn)已編譯代碼的詳細(xì)信息。
-
class
dis.Bytecode(x, *, first_line=None, current_offset=None)? 分析的字節(jié)碼對(duì)應(yīng)于函數(shù)、生成器、異步生成器、協(xié)程、方法、源代碼字符串或代碼對(duì)象(由
compile()返回)。這是下面列出的許多函數(shù)的便利包裝,最值得注意的是
get_instructions(),迭代于Bytecode的實(shí)例產(chǎn)生字節(jié)碼操作Instruction的實(shí)例。如果 first_line 不是
None,則表示應(yīng)該為反匯編代碼中的第一個(gè)源代碼行報(bào)告的行號(hào)。否則,源行信息(如果有的話)直接來(lái)自反匯編的代碼對(duì)象。如果 current_offset 不是
None,則它指的是反匯編代碼中的指令偏移量。設(shè)置它意味著dis()將針對(duì)指定的操作碼顯示“當(dāng)前指令”標(biāo)記。-
classmethod
from_traceback(tb)? 從給定回溯構(gòu)造一個(gè)
Bytecode實(shí)例,設(shè)置 current_offset 為異常負(fù)責(zé)的指令。
-
codeobj? 已編譯的代碼對(duì)象。
-
first_line? 代碼對(duì)象的第一個(gè)源代碼行(如果可用)
-
info()? 返回帶有關(guān)于代碼對(duì)象的詳細(xì)信息的格式化多行字符串,如
code_info()。
在 3.7 版更改: 現(xiàn)在可以處理協(xié)程和異步生成器對(duì)象。
-
classmethod
示例:
>>> bytecode = dis.Bytecode(myfunc)
>>> for instr in bytecode:
... print(instr.opname)
...
LOAD_GLOBAL
LOAD_FAST
CALL_FUNCTION
RETURN_VALUE
分析函數(shù)?
dis 模塊還定義了以下分析函數(shù),它們將輸入直接轉(zhuǎn)換為所需的輸出。如果只執(zhí)行單個(gè)操作,它們可能很有用,因此中間分析對(duì)象沒(méi)用:
-
dis.code_info(x)? 返回格式化的多行字符串,其包含詳細(xì)代碼對(duì)象信息的用于被提供的函數(shù)、生成器、異步生成器、協(xié)程、方法、源代碼字符串或代碼對(duì)象。
請(qǐng)注意,代碼信息字符串的確切內(nèi)容是高度依賴于實(shí)現(xiàn)的,它們可能會(huì)在Python VM或Python版本中任意更改。
3.2 新版功能.
在 3.7 版更改: 現(xiàn)在可以處理協(xié)程和異步生成器對(duì)象。
-
dis.show_code(x, *, file=None)? 將提供的函數(shù)、方法。源代碼字符串或代碼對(duì)象的詳細(xì)代碼對(duì)象信息打印到 file (如果未指定 file ,則為
sys.stdout)。這是
print(code_info(x), file= file)的便捷簡(jiǎn)寫,用于在解釋器提示符下進(jìn)行交互式探索。3.2 新版功能.
在 3.4 版更改: 添加 file 參數(shù)。
-
dis.dis(x=None, *, file=None, depth=None)? 反匯編 x 對(duì)象。 x 可以表示模塊、類、方法、函數(shù)、生成器、異步生成器、協(xié)程、代碼對(duì)象、源代碼字符串或原始字節(jié)碼的字節(jié)序列。對(duì)于模塊,它會(huì)反匯編所有功能。對(duì)于一個(gè)類,它反匯編所有方法(包括類和靜態(tài)方法)。對(duì)于代碼對(duì)象或原始字節(jié)碼序列,它每字節(jié)碼指令打印一行。它還遞歸地反匯編嵌套代碼對(duì)象(推導(dǎo)式代碼,生成器表達(dá)式和嵌套函數(shù),以及用于構(gòu)建嵌套類的代碼)。在被反匯編之前,首先使用
compile()內(nèi)置函數(shù)將字符串編譯為代碼對(duì)象。如果未提供任何對(duì)象,則此函數(shù)會(huì)反匯編最后一次回溯。如果提供的話,反匯編將作為文本寫入提供的 file 參數(shù),否則寫入
sys.stdout。遞歸的最大深度受 depth 限制,除非它是
None。depth=0表示沒(méi)有遞歸。在 3.4 版更改: 添加 file 參數(shù)。
在 3.7 版更改: 實(shí)現(xiàn)了遞歸反匯編并添加了 depth 參數(shù)。
在 3.7 版更改: 現(xiàn)在可以處理協(xié)程和異步生成器對(duì)象。
-
dis.distb(tb=None, *, file=None)? 如果沒(méi)有傳遞,則使用最后一個(gè)回溯來(lái)反匯編回溯的堆棧頂部函數(shù)。 指示了導(dǎo)致異常的指令。
如果提供的話,反匯編將作為文本寫入提供的 file 參數(shù),否則寫入
sys.stdout。在 3.4 版更改: 添加 file 參數(shù)。
-
dis.disassemble(code, lasti=-1, *, file=None)? -
dis.disco(code, lasti=-1, *, file=None)? 反匯編代碼對(duì)象,如果提供了 lasti ,則指示最后一條指令。輸出分為以下幾列:
行號(hào),用于每行的第一條指令
當(dāng)前指令,表示為
-->,一個(gè)標(biāo)記的指令,用
>>表示,指令的地址,
操作碼名稱,
操作參數(shù),和
括號(hào)中的參數(shù)解釋。
參數(shù)解釋識(shí)別本地和全局變量名稱、常量值、分支目標(biāo)和比較運(yùn)算符。
如果提供的話,反匯編將作為文本寫入提供的 file 參數(shù),否則寫入
sys.stdout。在 3.4 版更改: 添加 file 參數(shù)。
-
dis.get_instructions(x, *, first_line=None)? 在所提供的函數(shù)、方法、源代碼字符串或代碼對(duì)象中的指令上返回一個(gè)迭代器。
迭代器生成一系列
Instruction,命名為元組,提供所提供代碼中每個(gè)操作的詳細(xì)信息。如果 first_line 不是
None,則表示應(yīng)該為反匯編代碼中的第一個(gè)源代碼行報(bào)告的行號(hào)。否則,源行信息(如果有的話)直接來(lái)自反匯編的代碼對(duì)象。3.4 新版功能.
-
dis.findlinestarts(code)? 此生成器函數(shù)使用代碼對(duì)象 code 的
co_firstlineno和co_lnotab屬性來(lái)查找源代碼中行開(kāi)頭的偏移量。它們生成為(offset, lineno)` `對(duì)。請(qǐng)參閱 :source:`objects/lnotab_notes.txt` ,了解 ``co_lnotab格式以及如何解碼它。在 3.6 版更改: 行號(hào)可能會(huì)減少。 以前,他們總是在增加。
-
dis.findlabels(code)? 檢測(cè)作為跳轉(zhuǎn)目標(biāo)的原始編譯后字節(jié)碼字符串 code 中的所有偏移量,并返回這些偏移量的列表。
-
dis.stack_effect(opcode[, oparg])? 使用參數(shù) oparg 計(jì)算 opcode 的堆棧效果。
3.4 新版功能.
Python字節(jié)碼說(shuō)明?
get_instructions() 函數(shù)和 Bytecode 類提供字節(jié)碼指令的詳細(xì)信息的 Instruction 實(shí)例:
-
class
dis.Instruction? 字節(jié)碼操作的詳細(xì)信息
-
opname? 人類可讀的操作名稱
-
arg? 操作的數(shù)字參數(shù)(如果有的話),否則為
None
-
argval? 已解析的 arg 值(如果已知),否則與 arg 相同
-
argrepr? 人類可讀的操作參數(shù)描述
-
offset? 在字節(jié)碼序列中啟動(dòng)操作索引
-
starts_line? 行由此操作碼(如果有)啟動(dòng),否則為
None
-
is_jump_target? 如果其他代碼跳到這里,則為
True,否則為False
3.4 新版功能.
-
Python編譯器當(dāng)前生成以下字節(jié)碼指令。
一般指令
-
NOP? 什么都不做。 用作字節(jié)碼優(yōu)化器的占位符。
-
POP_TOP? 刪除堆棧頂部(TOS)項(xiàng)。
-
ROT_TWO? 交換兩個(gè)最頂層的堆棧項(xiàng)。
-
ROT_THREE? 將第二個(gè)和第三個(gè)堆棧項(xiàng)向上提升一個(gè)位置,頂項(xiàng)移動(dòng)到位置三。
-
DUP_TOP? 復(fù)制堆棧頂部的引用。
3.2 新版功能.
-
DUP_TOP_TWO? 復(fù)制堆棧頂部的兩個(gè)引用,使它們保持相同的順序。
3.2 新版功能.
一元操作
一元操作獲取堆棧頂部元素,應(yīng)用操作,并將結(jié)果推回堆棧。
-
UNARY_POSITIVE? 實(shí)現(xiàn)
TOS = +TOS。
-
UNARY_NEGATIVE? 實(shí)現(xiàn)
TOS = -TOS。
-
UNARY_NOT? 實(shí)現(xiàn)
TOS = not TOS。
-
UNARY_INVERT? 實(shí)現(xiàn)
TOS = ~TOS。
-
GET_ITER? 實(shí)現(xiàn)
TOS = iter(TOS)。
-
GET_YIELD_FROM_ITER? 如果
TOS是一個(gè) generator iterator 或 coroutine 對(duì)象則保持原樣。否則實(shí)現(xiàn)TOS = iter(TOS)。3.5 新版功能.
二元操作
二元操作從堆棧中刪除堆棧頂部(TOS)和第二個(gè)最頂層堆棧項(xiàng)(TOS1)。 它們執(zhí)行操作,并將結(jié)果放回堆棧。
-
BINARY_POWER? 實(shí)現(xiàn)
TOS = TOS1 ** TOS。
-
BINARY_MULTIPLY? 實(shí)現(xiàn)
TOS = TOS1 * TOS。
-
BINARY_MATRIX_MULTIPLY? 實(shí)現(xiàn)
TOS = TOS1 @ TOS。3.5 新版功能.
-
BINARY_FLOOR_DIVIDE? 實(shí)現(xiàn)
TOS = TOS1 // TOS。
-
BINARY_TRUE_DIVIDE? 實(shí)現(xiàn)
TOS = TOS1 / TOS。
-
BINARY_MODULO? 實(shí)現(xiàn)
TOS = TOS1 % TOS。
-
BINARY_ADD? 實(shí)現(xiàn)
TOS = TOS1 + TOS。
-
BINARY_SUBTRACT? 實(shí)現(xiàn)
TOS = TOS1 - TOS。
-
BINARY_SUBSCR? 實(shí)現(xiàn)
TOS = TOS1[TOS]。
-
BINARY_LSHIFT? 實(shí)現(xiàn)
TOS = TOS1 << TOS。
-
BINARY_RSHIFT? 實(shí)現(xiàn)
TOS = TOS1 >> TOS。
-
BINARY_AND? 實(shí)現(xiàn)
TOS = TOS1 & TOS。
-
BINARY_XOR? 實(shí)現(xiàn)
TOS = TOS1 ^ TOS。
-
BINARY_OR? 實(shí)現(xiàn)
TOS = TOS1 | TOS。
就地操作
就地操作就像二元操作,因?yàn)樗鼈儎h除了TOS和TOS1,并將結(jié)果推回到堆棧上,但是當(dāng)TOS1支持它時(shí),操作就地完成,并且產(chǎn)生的TOS可能是(但不一定) 原來(lái)的TOS1。
-
INPLACE_POWER? 就地實(shí)現(xiàn)
TOS = TOS1 ** TOS。
-
INPLACE_MULTIPLY? 就地實(shí)現(xiàn)
TOS = TOS1 * TOS。
-
INPLACE_MATRIX_MULTIPLY? 就地實(shí)現(xiàn)
TOS = TOS1 @ TOS。3.5 新版功能.
-
INPLACE_FLOOR_DIVIDE? 就地實(shí)現(xiàn)
TOS = TOS1 // TOS。
-
INPLACE_TRUE_DIVIDE? 就地實(shí)現(xiàn)
TOS = TOS1 / TOS。
-
INPLACE_MODULO? 就地實(shí)現(xiàn)
TOS = TOS1 % TOS。
-
INPLACE_ADD? 就地實(shí)現(xiàn)
TOS = TOS1 + TOS。
-
INPLACE_SUBTRACT? 就地實(shí)現(xiàn)
TOS = TOS1 - TOS。
-
INPLACE_LSHIFT? 就地實(shí)現(xiàn)
TOS = TOS1 << TOS。
-
INPLACE_RSHIFT? 就地實(shí)現(xiàn)
TOS = TOS1 >> TOS。
-
INPLACE_AND? 就地實(shí)現(xiàn)
TOS = TOS1 & TOS。
-
INPLACE_XOR? 就地實(shí)現(xiàn)
TOS = TOS1 ^ TOS。
-
INPLACE_OR? 就地實(shí)現(xiàn)
TOS = TOS1 | TOS。
-
STORE_SUBSCR? 實(shí)現(xiàn)
TOS1[TOS] = TOS2。
-
DELETE_SUBSCR? 實(shí)現(xiàn)
del TOS1[TOS]。
協(xié)程操作碼
-
GET_AWAITABLE? 實(shí)現(xiàn)
TOS = get_awaitable(TOS),其中get_awaitable(o)返回o如果o是一個(gè)有 CO_ITERABLE_COROUTINE 標(biāo)志的協(xié)程對(duì)象或生成器對(duì)象,否則解析o.__await__。3.5 新版功能.
-
GET_AITER? 實(shí)現(xiàn)
TOS = TOS.__aiter__()。3.5 新版功能.
在 3.7 版更改: 已經(jīng)不再支持從
__aiter__返回可等待對(duì)象。
-
GET_ANEXT? 實(shí)現(xiàn)
PUSH(get_awaitable(TOS.__anext__()))。參見(jiàn)GET_AWAITABLE獲取更多get_awaitable的細(xì)節(jié)3.5 新版功能.
-
BEFORE_ASYNC_WITH? 從棧頂元素解析
__aenter__和__aexit__。將__aexit__和__aenter__()的結(jié)果推入堆棧。3.5 新版功能.
-
SETUP_ASYNC_WITH? 創(chuàng)建一個(gè)新的幀對(duì)象。
3.5 新版功能.
其他操作碼
-
CONTINUE_LOOP(target)? Continues a loop due to a
continuestatement. target is the address to jump to (which should be aFOR_ITERinstruction).
-
SET_ADD(i)? 調(diào)用
set.add(TOS1[-i], TOS)。 用于實(shí)現(xiàn)集合推導(dǎo)。
-
LIST_APPEND(i)? 調(diào)用
list.append(TOS[-i], TOS)。 用于實(shí)現(xiàn)列表推導(dǎo)。
-
MAP_ADD(i)? Calls
dict.setitem(TOS1[-i], TOS, TOS1). Used to implement dict comprehensions.3.1 新版功能.
對(duì)于所有 SET_ADD 、 LIST_APPEND 和 MAP_ADD 指令,當(dāng)彈出添加的值或鍵值對(duì)時(shí),容器對(duì)象保留在堆棧上,以便它可用于循環(huán)的進(jìn)一步迭代。
-
RETURN_VALUE? 返回 TOS 到函數(shù)的調(diào)用者。
-
SETUP_ANNOTATIONS? 檢查
__annotations__是否在locals()中定義,如果沒(méi)有,它被設(shè)置為空dict。只有在類或模塊體靜態(tài)地包含 variable annotations 時(shí)才會(huì)發(fā)出此操作碼。3.6 新版功能.
-
IMPORT_STAR? 將所有不以
'_'開(kāi)頭的符號(hào)直接從模塊 TOS 加載到本地名稱空間。加載所有名稱后彈出該模塊。這個(gè)操作碼實(shí)現(xiàn)了from module import *。
-
POP_BLOCK? Removes one block from the block stack. Per frame, there is a stack of blocks, denoting nested loops, try statements, and such.
-
POP_EXCEPT? 從塊堆棧中刪除一個(gè)塊。 彈出的塊必須是異常處理程序塊,在進(jìn)入 except 處理程序時(shí)隱式創(chuàng)建。除了從幀堆棧彈出無(wú)關(guān)值之外,最后三個(gè)彈出值還用于恢復(fù)異常狀態(tài)。
-
END_FINALLY? Terminates a
finallyclause. The interpreter recalls whether the exception has to be re-raised, or whether the function returns, and continues with the outer-next block.
-
LOAD_BUILD_CLASS? 將
builtins .__ build_class__()推到堆棧上。它之后被CALL_FUNCTION調(diào)用來(lái)構(gòu)造一個(gè)類。
-
SETUP_WITH(delta)? This opcode performs several operations before a with block starts. First, it loads
__exit__()from the context manager and pushes it onto the stack for later use byWITH_CLEANUP. Then,__enter__()is called, and a finally block pointing to delta is pushed. Finally, the result of calling the enter method is pushed onto the stack. The next opcode will either ignore it (POP_TOP), or store it in (a) variable(s) (STORE_FAST,STORE_NAME, orUNPACK_SEQUENCE).3.2 新版功能.
-
WITH_CLEANUP_START? Cleans up the stack when a
withstatement block exits. TOS is the context manager's__exit__()bound method. Below TOS are 1--3 values indicating how/why the finally clause was entered:SECOND =
None(SECOND, THIRD) = (
WHY_{RETURN,CONTINUE}), retvalSECOND =
WHY_*; no retval below it(SECOND, THIRD, FOURTH) = exc_info()
In the last case,
TOS(SECOND, THIRD, FOURTH)is called, otherwiseTOS(None, None, None). Pushes SECOND and result of the call to the stack.
-
WITH_CLEANUP_FINISH? Pops exception type and result of 'exit' function call from the stack.
If the stack represents an exception, and the function call returns a 'true' value, this information is "zapped" and replaced with a single
WHY_SILENCEDto preventEND_FINALLYfrom re-raising the exception. (But non-local gotos will still be resumed.)
以下所有操作碼均使用其參數(shù)。
-
STORE_NAME(namei)? 實(shí)現(xiàn)
name = TOS。 namei 是 name 在代碼對(duì)象的co_names屬性中的索引。 在可能的情況下,編譯器會(huì)嘗試使用STORE_FAST或STORE_GLOBAL。
-
DELETE_NAME(namei)? 實(shí)現(xiàn)
del name,其中 namei 是代碼對(duì)象的co_names屬性的索引。
-
UNPACK_SEQUENCE(count)? 將 TOS 解包為 count 個(gè)單獨(dú)的值,它們將按從右至左的順序被放入堆棧。
-
UNPACK_EX(counts)? 實(shí)現(xiàn)使用帶星號(hào)的目標(biāo)進(jìn)行賦值:將 TOS 中的可迭代對(duì)象解包為單獨(dú)的值,其中值的總數(shù)可以小于可迭代對(duì)象中的項(xiàng)數(shù):新值之一將是由所有剩余項(xiàng)構(gòu)成的列表。
counts 的低字節(jié)是列表值之前的值的數(shù)量,counts 中的高字節(jié)則是之后的值的數(shù)量。 結(jié)果值會(huì)按從右至左的順序入棧。
-
STORE_ATTR(namei)? 實(shí)現(xiàn)
TOS.name = TOS1,其中 namei 是 name 在co_names中的索引號(hào)。
-
DELETE_ATTR(namei)? 實(shí)現(xiàn)
del TOS.name,使用 namei 作為co_names中的索引號(hào)。
-
STORE_GLOBAL(namei)? 類似于
STORE_NAME但會(huì)將 name 存儲(chǔ)為全局變量。
-
DELETE_GLOBAL(namei)? 類似于
DELETE_NAME但會(huì)刪除一個(gè)全局變量。
-
LOAD_CONST(consti)? 將
co_consts[consti]推入棧頂。
-
LOAD_NAME(namei)? 將與
co_names[namei]相關(guān)聯(lián)的值推入棧頂。
-
BUILD_TUPLE(count)? 創(chuàng)建一個(gè)使用了來(lái)自棧的 count 個(gè)項(xiàng)的元組,并將結(jié)果元組推入棧頂。
-
BUILD_LIST(count)? 類似于
BUILD_TUPLE但會(huì)創(chuàng)建一個(gè)列表。
-
BUILD_SET(count)? 類似于
BUILD_TUPLE但會(huì)創(chuàng)建一個(gè)集合。
-
BUILD_MAP(count)? 將一個(gè)新字典對(duì)象推入棧頂。 彈出
2 * count項(xiàng)使得字典包含 count 個(gè)條目:{..., TOS3: TOS2, TOS1: TOS}。在 3.5 版更改: 字典是根據(jù)棧中的項(xiàng)創(chuàng)建而不是創(chuàng)建一個(gè)預(yù)設(shè)大小包含 count 項(xiàng)的空字典。
-
BUILD_CONST_KEY_MAP(count)? BUILD_MAP版本專用于常量鍵。 彈出的棧頂元素包含一個(gè)由鍵構(gòu)成的元組,然后從TOS1開(kāi)始從構(gòu)建字典的值中彈出 count 個(gè)值。3.6 新版功能.
-
BUILD_STRING(count)? 拼接 count 個(gè)來(lái)自棧的字符串并將結(jié)果字符串推入棧頂。
3.6 新版功能.
-
BUILD_TUPLE_UNPACK(count)? 從棧中彈出 count 個(gè)可迭代對(duì)象,將它們合并為單個(gè)元組,并將結(jié)果推入棧頂。 實(shí)現(xiàn)可迭代對(duì)象解包為元組形式
(*x, *y, *z)。3.5 新版功能.
-
BUILD_TUPLE_UNPACK_WITH_CALL(count)? 這類似于
BUILD_TUPLE_UNPACK但專用于f(*x, *y, *z)調(diào)用語(yǔ)法。 棧中count + 1位置上的項(xiàng)應(yīng)當(dāng)是相應(yīng)的可調(diào)用對(duì)象f。3.6 新版功能.
-
BUILD_LIST_UNPACK(count)? 這類似于
BUILD_TUPLE_UNPACK但會(huì)將一個(gè)列表而非元組推入棧頂。 實(shí)現(xiàn)可迭代對(duì)象解包為列表形式[*x, *y, *z]。3.5 新版功能.
-
BUILD_SET_UNPACK(count)? 這類似于
BUILD_TUPLE_UNPACK但會(huì)將一個(gè)集合而非元組推入棧頂。 實(shí)現(xiàn)可迭代對(duì)象解包為集合形式{*x, *y, *z}。3.5 新版功能.
-
BUILD_MAP_UNPACK(count)? 從棧中彈出 count 個(gè)映射對(duì)象,將它們合并為單個(gè)字典,并將結(jié)果推入棧頂。 實(shí)現(xiàn)字典解包為字典形式
{**x, **y, **z}。3.5 新版功能.
-
BUILD_MAP_UNPACK_WITH_CALL(count)? 這類似于
BUILD_MAP_UNPACK但專用于f(**x, **y, **z)調(diào)用語(yǔ)法。 棧中count + 2位置上的項(xiàng)應(yīng)當(dāng)是相應(yīng)的可調(diào)用對(duì)象f。3.5 新版功能.
在 3.6 版更改: 可迭代對(duì)象的位置的確定方式是將操作碼參數(shù)加 2 而不是將其編碼到參數(shù)的第二個(gè)字節(jié)。
-
LOAD_ATTR(namei)? 將 TOS 替換為
getattr(TOS, co_names[namei])。
-
COMPARE_OP(opname)? 執(zhí)行布爾運(yùn)算操作。 操作名稱可在
cmp_op[opname]中找到。
-
IMPORT_NAME(namei)? 導(dǎo)入模塊
co_names[namei]。 會(huì)彈出 TOS 和 TOS1 以提供 fromlist 和 level 參數(shù)給__import__()。 模塊對(duì)象會(huì)被推入棧頂。 當(dāng)前命名空間不受影響:對(duì)于一條標(biāo)準(zhǔn) import 語(yǔ)句,會(huì)執(zhí)行后續(xù)的STORE_FAST指令來(lái)修改命名空間。
-
IMPORT_FROM(namei)? 從在 TOS 內(nèi)找到的模塊中加載屬性
co_names[namei]。 結(jié)果對(duì)象會(huì)被推入棧頂,以便由后續(xù)的STORE_FAST指令來(lái)保存。
-
JUMP_FORWARD(delta)? 將字節(jié)碼計(jì)數(shù)器的值增加 delta。
-
POP_JUMP_IF_TRUE(target)? 如果 TOS 為真值,則將字節(jié)碼計(jì)數(shù)器的值設(shè)為 target。 TOS 會(huì)被彈出。
3.1 新版功能.
-
POP_JUMP_IF_FALSE(target)? 如果 TOS 為假值,則將字節(jié)碼計(jì)數(shù)器的值設(shè)為 target。 TOS 會(huì)被彈出。
3.1 新版功能.
-
JUMP_IF_TRUE_OR_POP(target)? 如果 TOS 為真值,則將字節(jié)碼計(jì)數(shù)器的值設(shè)為 target 并將 TOS 留在棧頂。 否則(如 TOS 為假值),TOS 會(huì)被彈出。
3.1 新版功能.
-
JUMP_IF_FALSE_OR_POP(target)? 如果 TOS 為假值,則將字節(jié)碼計(jì)數(shù)器的值設(shè)為 target 并將 TOS 留在棧頂。 否則(如 TOS 為真值),TOS 會(huì)被彈出。
3.1 新版功能.
-
JUMP_ABSOLUTE(target)? 將字節(jié)碼計(jì)數(shù)器的值設(shè)為 target。
-
FOR_ITER(delta)? TOS 是一個(gè) iterator。 可調(diào)用它的
__next__()方法。 如果產(chǎn)生了一個(gè)新值,則將其推入棧頂(將迭代器留在其下方)。 如果迭代器提示已耗盡則 TOS 會(huì)被彈出,并將字節(jié)碼計(jì)數(shù)器的值增加 delta。
-
LOAD_GLOBAL(namei)? 加載名稱為
co_names[namei]的全局對(duì)象推入棧頂。
-
SETUP_LOOP(delta)? Pushes a block for a loop onto the block stack. The block spans from the current instruction with a size of delta bytes.
-
SETUP_EXCEPT(delta)? Pushes a try block from a try-except clause onto the block stack. delta points to the first except block.
-
SETUP_FINALLY(delta)? Pushes a try block from a try-except clause onto the block stack. delta points to the finally block.
-
LOAD_FAST(var_num)? 將指向局部對(duì)象
co_varnames[var_num]的引用推入棧頂。
-
STORE_FAST(var_num)? 將 TOS 存放到局部變量
co_varnames[var_num]。
-
DELETE_FAST(var_num)? 移除局部對(duì)象
co_varnames[var_num]。
-
LOAD_CLOSURE(i)? 將一個(gè)包含在單元的第 i 個(gè)空位中的對(duì)單元的引用推入棧頂并釋放可用的存儲(chǔ)空間。 如果 i 小于 co_cellvars 的長(zhǎng)度則變量的名稱為
co_cellvars[i]。 否則為co_freevars[i - len(co_cellvars)]。
-
LOAD_DEREF(i)? 加載包含在單元的第 i 個(gè)空位中的單元并釋放可用的存儲(chǔ)空間。 將一個(gè)對(duì)單元所包含對(duì)象的引用推入棧頂。
-
LOAD_CLASSDEREF(i)? 類似于
LOAD_DEREF但在查詢單元之前會(huì)首先檢查局部對(duì)象字典。 這被用于加載類語(yǔ)句體中的自由變量。3.4 新版功能.
-
STORE_DEREF(i)? 將 TOS 存放到包含在單元的第 i 個(gè)空位中的單元內(nèi)并釋放可用存儲(chǔ)空間。
-
RAISE_VARARGS(argc)? 使用
raise語(yǔ)句的 3 種形式之一引發(fā)異常,具體形式取決于 argc 的值:0:
raise(重新引發(fā)之前的異常)1:
raise TOS(在TOS上引發(fā)異常實(shí)例或類型)2:
raise TOS1 from TOS(在TOS1上引發(fā)異常實(shí)例或類型并將__cause__設(shè)為TOS)
-
CALL_FUNCTION(argc)? 調(diào)用一個(gè)可調(diào)用對(duì)象并傳入位置參數(shù)。 argc 指明位置參數(shù)的數(shù)量。 棧頂包含位置參數(shù),其中最右邊的參數(shù)在最頂端。 在參數(shù)之下是一個(gè)待調(diào)用的可調(diào)用對(duì)象。
CALL_FUNCTION會(huì)從棧中彈出所有參數(shù)以及可調(diào)用對(duì)象,附帶這些參數(shù)調(diào)用該可調(diào)用對(duì)象,并將可調(diào)用對(duì)象所返回的返回值推入棧頂。在 3.6 版更改: 此操作碼僅用于附帶位置參數(shù)的調(diào)用。
-
CALL_FUNCTION_KW(argc)? 調(diào)用一個(gè)可調(diào)用對(duì)象并傳入位置參數(shù)(如果有的話)和關(guān)鍵字參數(shù)。 argc 指明位置參數(shù)和關(guān)鍵字參數(shù)的總數(shù)量。 棧頂元素包含一個(gè)關(guān)鍵字參數(shù)名稱的元組。 在元組之下是根據(jù)元組排序的關(guān)鍵字參數(shù)。 在關(guān)鍵字參數(shù)之下是位置參數(shù),其中最右邊的參數(shù)在最頂端。 在參數(shù)之下是一個(gè)待調(diào)用的可調(diào)用對(duì)象。
CALL_FUNCTION_KW會(huì)從棧中彈出所有參數(shù)以及可調(diào)用對(duì)象,附帶這些參數(shù)調(diào)用該可調(diào)用對(duì)象,并將可調(diào)用對(duì)象所返回的返回值推入棧頂。在 3.6 版更改: 關(guān)鍵字參數(shù)會(huì)被打包為一個(gè)元組而非字典,argc 指明參數(shù)的總數(shù)量。
-
CALL_FUNCTION_EX(flags)? 調(diào)用一個(gè)可調(diào)用對(duì)象并附帶位置參數(shù)和關(guān)鍵字參數(shù)變量集合。 如果設(shè)置了 flags 的最低位,則棧頂包含一個(gè)由額外關(guān)鍵字參數(shù)組成的映射對(duì)象。 在該對(duì)象之下是一個(gè)包含位置參數(shù)的可迭代對(duì)象和一個(gè)待調(diào)用的可調(diào)用對(duì)象。
BUILD_MAP_UNPACK_WITH_CALL和BUILD_TUPLE_UNPACK_WITH_CALL可用于合并多個(gè)映射對(duì)象和包含參數(shù)的可迭代對(duì)象。 在該可調(diào)用對(duì)象被調(diào)用之前,映射對(duì)象和可迭代對(duì)象會(huì)被分別“解包”并將它們的內(nèi)容分別作為關(guān)鍵字參數(shù)和位置參數(shù)傳入。CALL_FUNCTION_EX會(huì)從棧中彈出所有參數(shù)以及可調(diào)用對(duì)象,附帶這些參數(shù)調(diào)用該可調(diào)用對(duì)象,并將可調(diào)用對(duì)象所返回的返回值推入棧頂。3.6 新版功能.
-
LOAD_METHOD(namei)? 從 TOS 對(duì)象加載一個(gè)名為
co_names[namei]的方法。 TOS 將被彈出。 此字節(jié)碼可區(qū)分兩種情況:如果 TOS 有一個(gè)名稱正確的方法,字節(jié)碼會(huì)將未綁定方法和 TOS 推入棧頂。 TOS 將在調(diào)用未綁定方法時(shí)被用作CALL_METHOD的第一個(gè)參數(shù) (self)。 否則會(huì)將NULL和屬性查找所返回的對(duì)象推入棧頂。3.7 新版功能.
-
CALL_METHOD(argc)? 調(diào)用一個(gè)方法。 argc 是位置參數(shù)的數(shù)量。 關(guān)鍵字參數(shù)不受支持。 此操作碼被設(shè)計(jì)用于配合
LOAD_METHOD使用。 位置參數(shù)放在棧頂。 在它們之下放在棧中的是由LOAD_METHOD所描述的兩個(gè)條目(或者是self和一個(gè)未綁定方法對(duì)象,或者是NULL和一個(gè)任意可調(diào)用對(duì)象)。 它們會(huì)被全部彈出并將返回值推入棧頂。3.7 新版功能.
-
MAKE_FUNCTION(flags)? 將一個(gè)新函數(shù)對(duì)象推入棧頂。 從底端到頂端,如果參數(shù)帶有指定的旗標(biāo)值則所使用的棧必須由這些值組成。
0x01是一個(gè)默認(rèn)值的元組,用于按位置排序的僅限位置形參以及位置或關(guān)鍵字形參0x02是一個(gè)僅限關(guān)鍵字形參的默認(rèn)值的字典0x04是一個(gè)標(biāo)注字典0x08一個(gè)包含用于自由變量的單元的元組,生成一個(gè)閉包與函數(shù) (在 TOS1) 相關(guān)聯(lián)的代碼
函數(shù)的 qualified name (在 TOS)
-
BUILD_SLICE(argc)? 將一個(gè)切片對(duì)象推入棧頂。 argc 必須為 2 或 3。 如果為 2,則推入
slice(TOS1, TOS);如果為 3,則推入slice(TOS2, TOS1, TOS)。 請(qǐng)參閱slice()內(nèi)置函數(shù)了解詳細(xì)信息。
-
EXTENDED_ARG(ext)? 為任意帶有大到無(wú)法放入默認(rèn)的單字節(jié)的參數(shù)的操作碼添加前綴。 ext 存放一個(gè)附加字節(jié)作為參數(shù)中的高比特位。 對(duì)于每個(gè)操作碼,最多允許三個(gè)
EXTENDED_ARG前綴,構(gòu)成兩字節(jié)到三字節(jié)的參數(shù)。
-
FORMAT_VALUE(flags)? 用于實(shí)現(xiàn)格式化字面值字符串(f-字符串)。 從棧中彈出一個(gè)可選的 fmt_spec,然后是一個(gè)必須的 value。 flags 的解讀方式如下:
(flags & 0x03) == 0x00: value 按原樣格式化。(flags & 0x03) == 0x01: 在格式化 value 之前調(diào)用其str()。(flags & 0x03) == 0x02: 在格式化 value 之前調(diào)用其repr()。(flags & 0x03) == 0x03: 在格式化 value 之前調(diào)用其ascii()。(flags & 0x04) == 0x04: 從棧中彈出 fmt_spec 并使用它,否則使用空的 fmt_spec。
使用
PyObject_Format()執(zhí)行格式化。 結(jié)果會(huì)被推入棧頂。3.6 新版功能.
-
HAVE_ARGUMENT? 這不是一個(gè)真正的操作碼。 它用于標(biāo)明使用參數(shù)和不使用參數(shù)的操作碼 (分別為
< HAVE_ARGUMENT和>= HAVE_ARGUMENT) 之間的分隔線。在 3.6 版更改: 現(xiàn)在每條指令都帶有參數(shù),但操作碼
< HAVE_ARGUMENT會(huì)忽略它。 之前僅限操作碼>= HAVE_ARGUMENT帶有參數(shù)。
操作碼集合?
提供這些集合用于字節(jié)碼指令的自動(dòng)內(nèi)?。?/p>
-
dis.opname? 操作名稱序列,可使用字節(jié)碼來(lái)索引。
-
dis.opmap? 映射操作名稱到字節(jié)碼的字典
-
dis.cmp_op? 所有比較操作名稱的序列。
-
dis.hasconst? 訪問(wèn)常量的字節(jié)碼序列。
-
dis.hasfree? 訪問(wèn)自由變量的字節(jié)碼序列(請(qǐng)注意這里所說(shuō)的‘自由’是指在當(dāng)前作用域中被內(nèi)部作用域所引用的名稱,或在外部作用域中被此作用域所引用的名稱。 它 并不 包括對(duì)全局或內(nèi)置作用域的引用)。
-
dis.hasname? 按名稱訪問(wèn)屬性的字節(jié)碼序列
-
dis.hasjrel? 具有相對(duì)跳轉(zhuǎn)目標(biāo)的字節(jié)碼序列。
-
dis.hasjabs? 具有絕對(duì)跳轉(zhuǎn)目標(biāo)的字節(jié)碼序列。
-
dis.haslocal? 訪問(wèn)局部變量的字節(jié)碼序列。
-
dis.hascompare? 布爾運(yùn)算的字節(jié)碼序列
