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è)源代碼行(如果可用)

dis()?

返回字節(jié)碼操作的格式化視圖(與 dis.dis() 打印相同,但作為多行字符串返回)。

info()?

返回帶有關(guān)于代碼對(duì)象的詳細(xì)信息的格式化多行字符串,如 code_info() 。

在 3.7 版更改: 現(xiàn)在可以處理協(xié)程和異步生成器對(duì)象。

示例:

>>> 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 ,則指示最后一條指令。輸出分為以下幾列:

  1. 行號(hào),用于每行的第一條指令

  2. 當(dāng)前指令,表示為 --> ,

  3. 一個(gè)標(biāo)記的指令,用 >> 表示,

  4. 指令的地址,

  5. 操作碼名稱,

  6. 操作參數(shù),和

  7. 括號(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ì)象 codeco_firstlinenoco_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ì)信息

opcode?

操作的數(shù)字代碼,對(duì)應(yīng)于下面列出的操作碼值和 操作碼集合 中的字節(jié)碼值。

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 iteratorcoroutine 對(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 新版功能.

其他操作碼

PRINT_EXPR?

實(shí)現(xiàn)交互模式的表達(dá)式語(yǔ)句。TOS從堆棧中被移除并打印。在非交互模式下,表達(dá)式語(yǔ)句以 POP_TOP 終止。

BREAK_LOOP?

Terminates a loop due to a break statement.

CONTINUE_LOOP(target)?

Continues a loop due to a continue statement. target is the address to jump to (which should be a FOR_ITER instruction).

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_APPENDMAP_ADD 指令,當(dāng)彈出添加的值或鍵值對(duì)時(shí),容器對(duì)象保留在堆棧上,以便它可用于循環(huán)的進(jìn)一步迭代。

RETURN_VALUE?

返回 TOS 到函數(shù)的調(diào)用者。

YIELD_VALUE?

彈出 TOS 并從一個(gè) generator 生成它。

YIELD_FROM?

彈出 TOS 并將其委托給它作為 generator 的子迭代器。

3.3 新版功能.

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 finally clause. 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 by WITH_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, or UNPACK_SEQUENCE).

3.2 新版功能.

WITH_CLEANUP_START?

Cleans up the stack when a with statement 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}), retval

  • SECOND = WHY_*; no retval below it

  • (SECOND, THIRD, FOURTH) = exc_info()

In the last case, TOS(SECOND, THIRD, FOURTH) is called, otherwise TOS(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_SILENCED to prevent END_FINALLY from re-raising the exception. (But non-local gotos will still be resumed.)

以下所有操作碼均使用其參數(shù)。

STORE_NAME(namei)?

實(shí)現(xiàn) name = TOS。 nameiname 在代碼對(duì)象的 co_names 屬性中的索引。 在可能的情況下,編譯器會(huì)嘗試使用 STORE_FASTSTORE_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 以提供 fromlistlevel 參數(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ǔ)空間。

DELETE_DEREF(i)?

清空包含在單元的第 i 個(gè)空位中的單元并釋放可用存儲(chǔ)空間。 被用于 del 語(yǔ)句。

3.2 新版功能.

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_CALLBUILD_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é)碼序列