dis --- Python 字節碼反匯編器?

Source code: Lib/dis.py


dis 模塊通過反匯編支持CPython的 bytecode 分析。該模塊作為輸入的 CPython 字節碼在文件 Include/opcode.h 中定義,并由編譯器和解釋器使用。

CPython implementation detail: 字節碼是 CPython 解釋器的實現細節。不保證不會在Python版本之間添加、刪除或更改字節碼。不應考慮將此模塊的跨 Python VM 或 Python 版本的使用。

在 3.6 版更改: 每條指令使用2個字節。以前字節數因指令而異。

示例:給出函數 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" 是行號)。

字節碼分析?

3.4 新版功能.

字節碼分析 API 允許將 Python 代碼片段包裝在 Bytecode 對象中,以便輕松訪問已編譯代碼的詳細信息。

class dis.Bytecode(x, *, first_line=None, current_offset=None)?

分析的字節碼對應于函數、生成器、異步生成器、協程、方法、源代碼字符串或代碼對象(由 compile() 返回)。

這是下面列出的許多函數的便利包裝,最值得注意的是 get_instructions() ,迭代于 Bytecode 的實例產生字節碼操作 Instruction 的實例。

如果 first_line 不是 None ,則表示應該為反匯編代碼中的第一個源代碼行報告的行號。否則,源行信息(如果有的話)直接來自反匯編的代碼對象。

如果 current_offset 不是 None ,則它指的是反匯編代碼中的指令偏移量。設置它意味著 dis() 將針對指定的操作碼顯示“當前指令”標記。

classmethod from_traceback(tb)?

從給定回溯構造一個 Bytecode 實例,設置 current_offset 為異常負責的指令。

codeobj?

已編譯的代碼對象。

first_line?

代碼對象的第一個源代碼行(如果可用)

dis()?

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

info()?

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

在 3.7 版更改: 現在可以處理協程和異步生成器對象。

示例:

>>> bytecode = dis.Bytecode(myfunc)
>>> for instr in bytecode:
...     print(instr.opname)
...
LOAD_GLOBAL
LOAD_FAST
CALL_FUNCTION
RETURN_VALUE

分析函數?

dis 模塊還定義了以下分析函數,它們將輸入直接轉換為所需的輸出。如果只執行單個操作,它們可能很有用,因此中間分析對象沒用:

dis.code_info(x)?

返回格式化的多行字符串,其包含詳細代碼對象信息的用于被提供的函數、生成器、異步生成器、協程、方法、源代碼字符串或代碼對象。

請注意,代碼信息字符串的確切內容是高度依賴于實現的,它們可能會在Python VM或Python版本中任意更改。

3.2 新版功能.

在 3.7 版更改: 現在可以處理協程和異步生成器對象。

dis.show_code(x, *, file=None)?

將提供的函數、方法。源代碼字符串或代碼對象的詳細代碼對象信息打印到 file (如果未指定 file ,則為 sys.stdout )。

這是 print(code_info(x), file= file) 的便捷簡寫,用于在解釋器提示符下進行交互式探索。

3.2 新版功能.

在 3.4 版更改: 添加 file 參數。

dis.dis(x=None, *, file=None, depth=None)?

反匯編 x 對象。 x 可以表示模塊、類、方法、函數、生成器、異步生成器、協程、代碼對象、源代碼字符串或原始字節碼的字節序列。對于模塊,它會反匯編所有功能。對于一個類,它反匯編所有方法(包括類和靜態方法)。對于代碼對象或原始字節碼序列,它每字節碼指令打印一行。它還遞歸地反匯編嵌套代碼對象(推導式代碼,生成器表達式和嵌套函數,以及用于構建嵌套類的代碼)。在被反匯編之前,首先使用 compile() 內置函數將字符串編譯為代碼對象。如果未提供任何對象,則此函數會反匯編最后一次回溯。

如果提供的話,反匯編將作為文本寫入提供的 file 參數,否則寫入 sys.stdout

遞歸的最大深度受 depth 限制,除非它是 Nonedepth=0 表示沒有遞歸。

在 3.4 版更改: 添加 file 參數。

在 3.7 版更改: 實現了遞歸反匯編并添加了 depth 參數。

在 3.7 版更改: 現在可以處理協程和異步生成器對象。

dis.distb(tb=None, *, file=None)?

如果沒有傳遞,則使用最后一個回溯來反匯編回溯的堆棧頂部函數。 指示了導致異常的指令。

如果提供的話,反匯編將作為文本寫入提供的 file 參數,否則寫入 sys.stdout

在 3.4 版更改: 添加 file 參數。

dis.disassemble(code, lasti=-1, *, file=None)?
dis.disco(code, lasti=-1, *, file=None)?

反匯編代碼對象,如果提供了 lasti ,則指示最后一條指令。輸出分為以下幾列:

  1. 行號,用于每行的第一條指令

  2. 當前指令,表示為 -->

  3. 一個標記的指令,用 >> 表示,

  4. 指令的地址,

  5. 操作碼名稱,

  6. 操作參數,和

  7. 括號中的參數解釋。

參數解釋識別本地和全局變量名稱、常量值、分支目標和比較運算符。

如果提供的話,反匯編將作為文本寫入提供的 file 參數,否則寫入 sys.stdout

在 3.4 版更改: 添加 file 參數。

dis.get_instructions(x, *, first_line=None)?

在所提供的函數、方法、源代碼字符串或代碼對象中的指令上返回一個迭代器。

迭代器生成一系列 Instruction ,命名為元組,提供所提供代碼中每個操作的詳細信息。

如果 first_line 不是 None ,則表示應該為反匯編代碼中的第一個源代碼行報告的行號。否則,源行信息(如果有的話)直接來自反匯編的代碼對象。

3.4 新版功能.

dis.findlinestarts(code)?

此生成器函數使用代碼對象 codeco_firstlinenoco_lnotab 屬性來查找源代碼中行開頭的偏移量。它們生成為 (offset, lineno)` `對。請參閱 :source:`objects/lnotab_notes.txt` ,了解 ``co_lnotab 格式以及如何解碼它。

在 3.6 版更改: 行號可能會減少。 以前,他們總是在增加。

dis.findlabels(code)?

檢測作為跳轉目標的原始編譯后字節碼字符串 code 中的所有偏移量,并返回這些偏移量的列表。

dis.stack_effect(opcode[, oparg])?

使用參數 oparg 計算 opcode 的堆棧效果。

3.4 新版功能.

Python字節碼說明?

get_instructions() 函數和 Bytecode 類提供字節碼指令的詳細信息的 Instruction 實例:

class dis.Instruction?

字節碼操作的詳細信息

opcode?

操作的數字代碼,對應于下面列出的操作碼值和 操作碼集合 中的字節碼值。

opname?

人類可讀的操作名稱

arg?

操作的數字參數(如果有的話),否則為 None

argval?

已解析的 arg 值(如果已知),否則與 arg 相同

argrepr?

人類可讀的操作參數描述

offset?

在字節碼序列中啟動操作索引

starts_line?

行由此操作碼(如果有)啟動,否則為 None

is_jump_target?

如果其他代碼跳到這里,則為 True ,否則為 False

3.4 新版功能.

Python編譯器當前生成以下字節碼指令。

一般指令

NOP?

什么都不做。 用作字節碼優化器的占位符。

POP_TOP?

刪除堆棧頂部(TOS)項。

ROT_TWO?

交換兩個最頂層的堆棧項。

ROT_THREE?

將第二個和第三個堆棧項向上提升一個位置,頂項移動到位置三。

DUP_TOP?

復制堆棧頂部的引用。

3.2 新版功能.

DUP_TOP_TWO?

復制堆棧頂部的兩個引用,使它們保持相同的順序。

3.2 新版功能.

一元操作

一元操作獲取堆棧頂部元素,應用操作,并將結果推回堆棧。

UNARY_POSITIVE?

實現 TOS = +TOS

UNARY_NEGATIVE?

實現 TOS = -TOS

UNARY_NOT?

實現 TOS = not TOS

UNARY_INVERT?

實現 TOS = ~TOS

GET_ITER?

實現 TOS = iter(TOS)

GET_YIELD_FROM_ITER?

如果 TOS 是一個 generator iteratorcoroutine 對象則保持原樣。否則實現 TOS = iter(TOS)

3.5 新版功能.

二元操作

二元操作從堆棧中刪除堆棧頂部(TOS)和第二個最頂層堆棧項(TOS1)。 它們執行操作,并將結果放回堆棧。

BINARY_POWER?

實現 TOS = TOS1 ** TOS

BINARY_MULTIPLY?

實現 TOS = TOS1 * TOS

BINARY_MATRIX_MULTIPLY?

實現 TOS = TOS1 @ TOS

3.5 新版功能.

BINARY_FLOOR_DIVIDE?

實現 TOS = TOS1 // TOS

BINARY_TRUE_DIVIDE?

實現 TOS = TOS1 / TOS

BINARY_MODULO?

實現 TOS = TOS1 % TOS

BINARY_ADD?

實現 TOS = TOS1 + TOS

BINARY_SUBTRACT?

實現 TOS = TOS1 - TOS

BINARY_SUBSCR?

實現 TOS = TOS1[TOS]

BINARY_LSHIFT?

實現 TOS = TOS1 << TOS

BINARY_RSHIFT?

實現 TOS = TOS1 >> TOS

BINARY_AND?

實現 TOS = TOS1 & TOS

BINARY_XOR?

實現 TOS = TOS1 ^ TOS

BINARY_OR?

實現 TOS = TOS1 | TOS

就地操作

就地操作就像二元操作,因為它們刪除了TOS和TOS1,并將結果推回到堆棧上,但是當TOS1支持它時,操作就地完成,并且產生的TOS可能是(但不一定) 原來的TOS1。

INPLACE_POWER?

就地實現 TOS = TOS1 ** TOS

INPLACE_MULTIPLY?

就地實現 TOS = TOS1 * TOS

INPLACE_MATRIX_MULTIPLY?

就地實現 TOS = TOS1 @ TOS

3.5 新版功能.

INPLACE_FLOOR_DIVIDE?

就地實現 TOS = TOS1 // TOS

INPLACE_TRUE_DIVIDE?

就地實現 TOS = TOS1 / TOS

INPLACE_MODULO?

就地實現 TOS = TOS1 % TOS

INPLACE_ADD?

就地實現 TOS = TOS1 + TOS

INPLACE_SUBTRACT?

就地實現 TOS = TOS1 - TOS

INPLACE_LSHIFT?

就地實現 TOS = TOS1 << TOS

INPLACE_RSHIFT?

就地實現 TOS = TOS1 >> TOS

INPLACE_AND?

就地實現 TOS = TOS1 & TOS

INPLACE_XOR?

就地實現 TOS = TOS1 ^ TOS

INPLACE_OR?

就地實現 TOS = TOS1 | TOS

STORE_SUBSCR?

實現 TOS1[TOS] = TOS2

DELETE_SUBSCR?

實現 del TOS1[TOS]

協程操作碼

GET_AWAITABLE?

實現 TOS = get_awaitable(TOS) ,其中 get_awaitable(o) 返回 o 如果 o 是一個有 CO_ITERABLE_COROUTINE 標志的協程對象或生成器對象,否則解析 o.__await__

3.5 新版功能.

GET_AITER?

實現 TOS = TOS.__aiter__()

3.5 新版功能.

在 3.7 版更改: 已經不再支持從 __aiter__ 返回可等待對象。

GET_ANEXT?

實現 PUSH(get_awaitable(TOS.__anext__())) 。參見 GET_AWAITABLE 獲取更多 get_awaitable 的細節

3.5 新版功能.

BEFORE_ASYNC_WITH?

從棧頂元素解析 __aenter____aexit__ 。將 __aexit____aenter__() 的結果推入堆棧。

3.5 新版功能.

SETUP_ASYNC_WITH?

創建一個新的幀對象。

3.5 新版功能.

其他操作碼

PRINT_EXPR?

實現交互模式的表達式語句。TOS從堆棧中被移除并打印。在非交互模式下,表達式語句以 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)?

調用 set.add(TOS1[-i], TOS) 。 用于實現集合推導。

LIST_APPEND(i)?

調用 list.append(TOS[-i], TOS) 。 用于實現列表推導。

MAP_ADD(i)?

Calls dict.setitem(TOS1[-i], TOS, TOS1). Used to implement dict comprehensions.

3.1 新版功能.

對于所有 SET_ADDLIST_APPENDMAP_ADD 指令,當彈出添加的值或鍵值對時,容器對象保留在堆棧上,以便它可用于循環的進一步迭代。

RETURN_VALUE?

返回 TOS 到函數的調用者。

YIELD_VALUE?

彈出 TOS 并從一個 generator 生成它。

YIELD_FROM?

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

3.3 新版功能.

SETUP_ANNOTATIONS?

檢查 __annotations__ 是否在 locals() 中定義,如果沒有,它被設置為空 dict 。只有在類或模塊體靜態地包含 variable annotations 時才會發出此操作碼。

3.6 新版功能.

IMPORT_STAR?

將所有不以 '_' 開頭的符號直接從模塊 TOS 加載到本地名稱空間。加載所有名稱后彈出該模塊。這個操作碼實現了 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?

從塊堆棧中刪除一個塊。 彈出的塊必須是異常處理程序塊,在進入 except 處理程序時隱式創建。除了從幀堆棧彈出無關值之外,最后三個彈出值還用于恢復異常狀態。

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 調用來構造一個類。

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

以下所有操作碼均使用其參數。

STORE_NAME(namei)?

實現 name = TOSnameiname 在代碼對象的 co_names 屬性中的索引。 在可能的情況下,編譯器會嘗試使用 STORE_FASTSTORE_GLOBAL

DELETE_NAME(namei)?

實現 del name ,其中 namei 是代碼對象的 co_names 屬性的索引。

UNPACK_SEQUENCE(count)?

將 TOS 解包為 count 個單獨的值,它們將按從右至左的順序被放入堆棧。

UNPACK_EX(counts)?

實現使用帶星號的目標進行賦值:將 TOS 中的可迭代對象解包為單獨的值,其中值的總數可以小于可迭代對象中的項數:新值之一將是由所有剩余項構成的列表。

counts 的低字節是列表值之前的值的數量,counts 中的高字節則是之后的值的數量。 結果值會按從右至左的順序入棧。

STORE_ATTR(namei)?

實現 TOS.name = TOS1,其中 namei 是 name 在 co_names 中的索引號。

DELETE_ATTR(namei)?

實現 del TOS.name,使用 namei 作為 co_names 中的索引號。

STORE_GLOBAL(namei)?

類似于 STORE_NAME 但會將 name 存儲為全局變量。

DELETE_GLOBAL(namei)?

類似于 DELETE_NAME 但會刪除一個全局變量。

LOAD_CONST(consti)?

co_consts[consti] 推入棧頂。

LOAD_NAME(namei)?

將與 co_names[namei] 相關聯的值推入棧頂。

BUILD_TUPLE(count)?

創建一個使用了來自棧的 count 個項的元組,并將結果元組推入棧頂。

BUILD_LIST(count)?

類似于 BUILD_TUPLE 但會創建一個列表。

BUILD_SET(count)?

類似于 BUILD_TUPLE 但會創建一個集合。

BUILD_MAP(count)?

將一個新字典對象推入棧頂。 彈出 2 * count 項使得字典包含 count 個條目: {..., TOS3: TOS2, TOS1: TOS}

在 3.5 版更改: 字典是根據棧中的項創建而不是創建一個預設大小包含 count 項的空字典。

BUILD_CONST_KEY_MAP(count)?

BUILD_MAP 版本專用于常量鍵。 彈出的棧頂元素包含一個由鍵構成的元組,然后從 TOS1 開始從構建字典的值中彈出 count 個值。

3.6 新版功能.

BUILD_STRING(count)?

拼接 count 個來自棧的字符串并將結果字符串推入棧頂。

3.6 新版功能.

BUILD_TUPLE_UNPACK(count)?

從棧中彈出 count 個可迭代對象,將它們合并為單個元組,并將結果推入棧頂。 實現可迭代對象解包為元組形式 (*x, *y, *z)

3.5 新版功能.

BUILD_TUPLE_UNPACK_WITH_CALL(count)?

這類似于 BUILD_TUPLE_UNPACK 但專用于 f(*x, *y, *z) 調用語法。 棧中 count + 1 位置上的項應當是相應的可調用對象 f

3.6 新版功能.

BUILD_LIST_UNPACK(count)?

這類似于 BUILD_TUPLE_UNPACK 但會將一個列表而非元組推入棧頂。 實現可迭代對象解包為列表形式 [*x, *y, *z]

3.5 新版功能.

BUILD_SET_UNPACK(count)?

這類似于 BUILD_TUPLE_UNPACK 但會將一個集合而非元組推入棧頂。 實現可迭代對象解包為集合形式 {*x, *y, *z}

3.5 新版功能.

BUILD_MAP_UNPACK(count)?

從棧中彈出 count 個映射對象,將它們合并為單個字典,并將結果推入棧頂。 實現字典解包為字典形式 {**x, **y, **z}

3.5 新版功能.

BUILD_MAP_UNPACK_WITH_CALL(count)?

這類似于 BUILD_MAP_UNPACK 但專用于 f(**x, **y, **z) 調用語法。 棧中 count + 2 位置上的項應當是相應的可調用對象 f

3.5 新版功能.

在 3.6 版更改: 可迭代對象的位置的確定方式是將操作碼參數加 2 而不是將其編碼到參數的第二個字節。

LOAD_ATTR(namei)?

將 TOS 替換為 getattr(TOS, co_names[namei])

COMPARE_OP(opname)?

執行布爾運算操作。 操作名稱可在 cmp_op[opname] 中找到。

IMPORT_NAME(namei)?

導入模塊 co_names[namei]。 會彈出 TOS 和 TOS1 以提供 fromlistlevel 參數給 __import__()。 模塊對象會被推入棧頂。 當前命名空間不受影響:對于一條標準 import 語句,會執行后續的 STORE_FAST 指令來修改命名空間。

IMPORT_FROM(namei)?

從在 TOS 內找到的模塊中加載屬性 co_names[namei]。 結果對象會被推入棧頂,以便由后續的 STORE_FAST 指令來保存。

JUMP_FORWARD(delta)?

將字節碼計數器的值增加 delta

POP_JUMP_IF_TRUE(target)?

如果 TOS 為真值,則將字節碼計數器的值設為 target。 TOS 會被彈出。

3.1 新版功能.

POP_JUMP_IF_FALSE(target)?

如果 TOS 為假值,則將字節碼計數器的值設為 target。 TOS 會被彈出。

3.1 新版功能.

JUMP_IF_TRUE_OR_POP(target)?

如果 TOS 為真值,則將字節碼計數器的值設為 target 并將 TOS 留在棧頂。 否則(如 TOS 為假值),TOS 會被彈出。

3.1 新版功能.

JUMP_IF_FALSE_OR_POP(target)?

如果 TOS 為假值,則將字節碼計數器的值設為 target 并將 TOS 留在棧頂。 否則(如 TOS 為真值),TOS 會被彈出。

3.1 新版功能.

JUMP_ABSOLUTE(target)?

將字節碼計數器的值設為 target

FOR_ITER(delta)?

TOS 是一個 iterator。 可調用它的 __next__() 方法。 如果產生了一個新值,則將其推入棧頂(將迭代器留在其下方)。 如果迭代器提示已耗盡則 TOS 會被彈出,并將字節碼計數器的值增加 delta

LOAD_GLOBAL(namei)?

加載名稱為 co_names[namei] 的全局對象推入棧頂。

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

將指向局部對象 co_varnames[var_num] 的引用推入棧頂。

STORE_FAST(var_num)?

將 TOS 存放到局部變量 co_varnames[var_num]

DELETE_FAST(var_num)?

移除局部對象 co_varnames[var_num]

LOAD_CLOSURE(i)?

將一個包含在單元的第 i 個空位中的對單元的引用推入棧頂并釋放可用的存儲空間。 如果 i 小于 co_cellvars 的長度則變量的名稱為 co_cellvars[i]。 否則為 co_freevars[i - len(co_cellvars)]

LOAD_DEREF(i)?

加載包含在單元的第 i 個空位中的單元并釋放可用的存儲空間。 將一個對單元所包含對象的引用推入棧頂。

LOAD_CLASSDEREF(i)?

類似于 LOAD_DEREF 但在查詢單元之前會首先檢查局部對象字典。 這被用于加載類語句體中的自由變量。

3.4 新版功能.

STORE_DEREF(i)?

將 TOS 存放到包含在單元的第 i 個空位中的單元內并釋放可用存儲空間。

DELETE_DEREF(i)?

清空包含在單元的第 i 個空位中的單元并釋放可用存儲空間。 被用于 del 語句。

3.2 新版功能.

RAISE_VARARGS(argc)?

使用 raise 語句的 3 種形式之一引發異常,具體形式取決于 argc 的值:

  • 0: raise (重新引發之前的異常)

  • 1: raise TOS (在 TOS 上引發異常實例或類型)

  • 2: raise TOS1 from TOS (在 TOS1 上引發異常實例或類型并將 __cause__ 設為 TOS)

CALL_FUNCTION(argc)?

調用一個可調用對象并傳入位置參數。 argc 指明位置參數的數量。 棧頂包含位置參數,其中最右邊的參數在最頂端。 在參數之下是一個待調用的可調用對象。 CALL_FUNCTION 會從棧中彈出所有參數以及可調用對象,附帶這些參數調用該可調用對象,并將可調用對象所返回的返回值推入棧頂。

在 3.6 版更改: 此操作碼僅用于附帶位置參數的調用。

CALL_FUNCTION_KW(argc)?

調用一個可調用對象并傳入位置參數(如果有的話)和關鍵字參數。 argc 指明位置參數和關鍵字參數的總數量。 棧頂元素包含一個關鍵字參數名稱的元組。 在元組之下是根據元組排序的關鍵字參數。 在關鍵字參數之下是位置參數,其中最右邊的參數在最頂端。 在參數之下是一個待調用的可調用對象。 CALL_FUNCTION_KW 會從棧中彈出所有參數以及可調用對象,附帶這些參數調用該可調用對象,并將可調用對象所返回的返回值推入棧頂。

在 3.6 版更改: 關鍵字參數會被打包為一個元組而非字典,argc 指明參數的總數量。

CALL_FUNCTION_EX(flags)?

調用一個可調用對象并附帶位置參數和關鍵字參數變量集合。 如果設置了 flags 的最低位,則棧頂包含一個由額外關鍵字參數組成的映射對象。 在該對象之下是一個包含位置參數的可迭代對象和一個待調用的可調用對象。 BUILD_MAP_UNPACK_WITH_CALLBUILD_TUPLE_UNPACK_WITH_CALL 可用于合并多個映射對象和包含參數的可迭代對象。 在該可調用對象被調用之前,映射對象和可迭代對象會被分別“解包”并將它們的內容分別作為關鍵字參數和位置參數傳入。 CALL_FUNCTION_EX 會從棧中彈出所有參數以及可調用對象,附帶這些參數調用該可調用對象,并將可調用對象所返回的返回值推入棧頂。

3.6 新版功能.

LOAD_METHOD(namei)?

從 TOS 對象加載一個名為 co_names[namei] 的方法。 TOS 將被彈出。 此字節碼可區分兩種情況:如果 TOS 有一個名稱正確的方法,字節碼會將未綁定方法和 TOS 推入棧頂。 TOS 將在調用未綁定方法時被用作 CALL_METHOD 的第一個參數 (self)。 否則會將 NULL 和屬性查找所返回的對象推入棧頂。

3.7 新版功能.

CALL_METHOD(argc)?

調用一個方法。 argc 是位置參數的數量。 關鍵字參數不受支持。 此操作碼被設計用于配合 LOAD_METHOD 使用。 位置參數放在棧頂。 在它們之下放在棧中的是由 LOAD_METHOD 所描述的兩個條目(或者是 self 和一個未綁定方法對象,或者是 NULL 和一個任意可調用對象)。 它們會被全部彈出并將返回值推入棧頂。

3.7 新版功能.

MAKE_FUNCTION(flags)?

將一個新函數對象推入棧頂。 從底端到頂端,如果參數帶有指定的旗標值則所使用的棧必須由這些值組成。

  • 0x01 是一個默認值的元組,用于按位置排序的僅限位置形參以及位置或關鍵字形參

  • 0x02 是一個僅限關鍵字形參的默認值的字典

  • 0x04 是一個標注字典

  • 0x08 一個包含用于自由變量的單元的元組,生成一個閉包

  • 與函數 (在 TOS1) 相關聯的代碼

  • 函數的 qualified name (在 TOS)

BUILD_SLICE(argc)?

將一個切片對象推入棧頂。 argc 必須為 2 或 3。 如果為 2,則推入 slice(TOS1, TOS);如果為 3,則推入 slice(TOS2, TOS1, TOS)。 請參閱 slice() 內置函數了解詳細信息。

EXTENDED_ARG(ext)?

為任意帶有大到無法放入默認的單字節的參數的操作碼添加前綴。 ext 存放一個附加字節作為參數中的高比特位。 對于每個操作碼,最多允許三個 EXTENDED_ARG 前綴,構成兩字節到三字節的參數。

FORMAT_VALUE(flags)?

用于實現格式化字面值字符串(f-字符串)。 從棧中彈出一個可選的 fmt_spec,然后是一個必須的 valueflags 的解讀方式如下:

  • (flags & 0x03) == 0x00: value 按原樣格式化。

  • (flags & 0x03) == 0x01: 在格式化 value 之前調用其 str()

  • (flags & 0x03) == 0x02: 在格式化 value 之前調用其 repr()

  • (flags & 0x03) == 0x03: 在格式化 value 之前調用其 ascii()

  • (flags & 0x04) == 0x04: 從棧中彈出 fmt_spec 并使用它,否則使用空的 fmt_spec

使用 PyObject_Format() 執行格式化。 結果會被推入棧頂。

3.6 新版功能.

HAVE_ARGUMENT?

這不是一個真正的操作碼。 它用于標明使用參數和不使用參數的操作碼 (分別為 < HAVE_ARGUMENT>= HAVE_ARGUMENT) 之間的分隔線。

在 3.6 版更改: 現在每條指令都帶有參數,但操作碼 < HAVE_ARGUMENT 會忽略它。 之前僅限操作碼 >= HAVE_ARGUMENT 帶有參數。

操作碼集合?

提供這些集合用于字節碼指令的自動內省:

dis.opname?

操作名稱序列,可使用字節碼來索引。

dis.opmap?

映射操作名稱到字節碼的字典

dis.cmp_op?

所有比較操作名稱的序列。

dis.hasconst?

訪問常量的字節碼序列。

dis.hasfree?

訪問自由變量的字節碼序列(請注意這里所說的‘自由’是指在當前作用域中被內部作用域所引用的名稱,或在外部作用域中被此作用域所引用的名稱。 它 并不 包括對全局或內置作用域的引用)。

dis.hasname?

按名稱訪問屬性的字節碼序列

dis.hasjrel?

具有相對跳轉目標的字節碼序列。

dis.hasjabs?

具有絕對跳轉目標的字節碼序列。

dis.haslocal?

訪問局部變量的字節碼序列。

dis.hascompare?

布爾運算的字節碼序列