dis --- Python 位元組碼反彙編器

原始碼: Lib/dis.py


dis 模組透過反彙編 CPython 的 位元組碼 來支援對它的分析。該模組接受的 CPython 位元組碼輸入在檔案 Include/opcode.h 中定義,並被編譯器和直譯器使用。

CPython 實現細節: 位元組碼是 CPython 直譯器的一種實現細節。不保證位元組碼不會在不同 Python 版本之間被新增、移除或更改。不應假定此模組的運用可在不同 Python 虛擬機器或 Python 釋出版之間保持有效。

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

在 3.10 版更改: 跳轉、異常處理和迴圈指令的引數現在是指令偏移量,而不是位元組偏移量。

在 3.11 版更改: 某些指令會附帶一個或多個內聯快取條目,其形式為 CACHE 指令。這些指令預設被隱藏,但可以透過向任何 dis 工具函式傳入 show_caches=True 來顯示。此外,直譯器現在會調整位元組碼以針對不同的執行時條件進行特化。特化後的自適應位元組碼可以透過傳入 adaptive=True 來顯示。

在 3.12 版更改: 跳轉指令的引數是目標指令相對於跳轉指令的 CACHE 條目之後緊鄰的指令的偏移量。

因此,CACHE 指令的存在對前向跳轉是透明的,但在分析後向跳轉時需要予以考慮。

在 3.13 版更改: 輸出會為跳轉目標和異常處理程式顯示邏輯標籤,而非指令偏移量。添加了 -O 命令列選項和 show_offsets 引數。

在 3.14 版更改: 添加了 -P 命令列選項和 show_positions 引數。

添加了 -S 命令列選項。

示例:對於函式 myfunc()

def myfunc(alist):
    return len(alist)

可以使用以下命令來顯示 myfunc() 的反彙編程式碼

>>> dis.dis(myfunc)
  2           RESUME                   0

  3           LOAD_GLOBAL              1 (len + NULL)
              LOAD_FAST_BORROW         0 (alist)
              CALL                     1
              RETURN_VALUE

(“2”是行號)。

命令列介面

dis 模組可以作為指令碼從命令列呼叫

python -m dis [-h] [-C] [-O] [-P] [-S] [infile]

接受以下選項

-h, --help

顯示用法並退出。

-C, --show-caches

顯示內聯快取。

在 3.13 版本加入。

-O, --show-offsets

顯示指令的偏移量。

在 3.13 版本加入。

-P, --show-positions

顯示指令在原始碼中的位置。

在 3.14 版本加入。

-S, --specialized

顯示特化的位元組碼。

在 3.14 版本加入。

如果指定了 infile,其反彙編程式碼將被寫入 stdout。否則,反彙編將對從 stdin 接收的已編譯原始碼執行。

位元組碼分析

在 3.4 版本加入。

位元組碼分析 API 允許將 Python 程式碼片段包裝在一個 Bytecode 物件中,該物件提供了對已編譯程式碼細節的便捷訪問。

class dis.Bytecode(x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False)

分析一個函式、生成器、非同步生成器、協程、方法、原始碼字串或程式碼物件(由 compile() 返回)對應的位元組碼。

這是對下面列出的許多函式的一個方便的包裝,尤其是 get_instructions(),因為迭代一個 Bytecode 例項會產生位元組碼操作的 Instruction 例項。

如果 first_line 不為 None,它表示在反彙編程式碼中為第一行原始碼報告的行號。否則,原始碼行資訊(如果有)直接從反彙編的程式碼物件中獲取。

如果 current_offset 不為 None,它指向反彙編程式碼中的一個指令偏移量。設定此值意味著 dis() 將在指定的 opcode 旁邊顯示一個“當前指令”標記。

如果 show_cachesTruedis() 將顯示直譯器用來特化位元組碼的內聯快取條目。

如果 adaptiveTruedis() 將顯示可能與原始位元組碼不同的特化位元組碼。

如果 show_offsetsTruedis() 將在輸出中包含指令偏移量。

如果 show_positionsTruedis() 將在輸出中包含指令的原始碼位置。

classmethod from_traceback(tb, *, show_caches=False)

根據給定的回溯資訊構造一個 Bytecode 例項,並將 current_offset 設定為導致異常的指令。

codeobj

已編譯的程式碼物件。

first_line

程式碼物件的第一個原始碼行號(如果可用)。

dis()

返回一個格式化的位元組碼操作檢視(與 dis.dis() 列印的內容相同,但作為多行字串返回)。

info()

返回一個格式化的多行字串,其中包含有關程式碼物件的詳細資訊,類似於 code_info()

在 3.7 版更改: 現在可以處理協程和非同步生成器物件。

在 3.11 版更改: 添加了 show_cachesadaptive 引數。

在 3.13 版更改: 添加了 show_offsets 引數

在 3.14 版更改: 添加了 show_positions 引數。

示例

>>> bytecode = dis.Bytecode(myfunc)
>>> for instr in bytecode:
...     print(instr.opname)
...
RESUME
LOAD_GLOBAL
LOAD_FAST_BORROW
CALL
RETURN_VALUE

分析函式

dis 模組還定義了以下分析函式,可將輸入直接轉換為所需輸出。如果只執行單個操作,因此中間分析物件沒有用處,它們可能會很有用。

dis.code_info(x)

為提供的函式、生成器、非同步生成器、協程、方法、原始碼字串或程式碼物件返回一個格式化的多行字串,其中包含詳細的程式碼物件資訊。

請注意,程式碼資訊字串的確切內容高度依賴於具體實現,並且可能在不同的 Python 虛擬機器或 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, show_caches=False, adaptive=False, show_offsets=False, show_positions=False)

反彙編 x 物件。x 可以表示模組、類、方法、函式、生成器、非同步生成器、協程、程式碼物件、原始碼字串或原始位元組碼的位元組序列。對於模組,它反彙編所有函式。對於類,它反彙編所有方法(包括類方法和靜態方法)。對於程式碼物件或原始位元組碼序列,它為每個位元組碼指令列印一行。它還會遞迴地反彙編巢狀的程式碼物件。這些可以包括生成器表示式、巢狀函式、巢狀類的主體以及用於 註解作用域 的程式碼物件。字串首先使用 compile() 內建函式編譯為程式碼物件,然後再進行反彙編。如果沒有提供物件,此函式將反彙編上一個回溯資訊。

如果提供了 file 引數,反彙編結果將作為文字寫入該檔案,否則寫入 sys.stdout

最大遞迴深度由 depth 限制,除非它為 Nonedepth=0 表示不遞迴。

如果 show_cachesTrue,此函式將顯示直譯器用於特化位元組碼的內聯快取條目。

如果 adaptiveTrue,此函式將顯示可能與原始位元組碼不同的特化位元組碼。

在 3.4 版更改: 添加了 file 引數。

在 3.7 版更改: 實現了遞迴反彙編並添加了 depth 引數。

在 3.7 版更改: 現在可以處理協程和非同步生成器物件。

在 3.11 版更改: 添加了 show_cachesadaptive 引數。

在 3.13 版更改: 添加了 show_offsets 引數。

在 3.14 版更改: 添加了 show_positions 引數。

dis.distb(tb=None, *, file=None, show_caches=False, adaptive=False, show_offset=False, show_positions=False)

反彙編回溯資訊中的棧頂函式,如果未傳入則使用最後的回溯資訊。導致異常的指令會被指出。

如果提供了 file 引數,反彙編結果將作為文字寫入該檔案,否則寫入 sys.stdout

在 3.4 版更改: 添加了 file 引數。

在 3.11 版更改: 添加了 show_cachesadaptive 引數。

在 3.13 版更改: 添加了 show_offsets 引數。

在 3.14 版更改: 添加了 show_positions 引數。

dis.disassemble(code, lasti=-1, *, file=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False)
dis.disco(code, lasti=-1, *, file=None, show_caches=False, adaptive=False, show_offsets=False, show_positions=False)

反彙編一個程式碼物件,如果提供了 lasti,則指示最後一條指令。輸出分為以下幾列:

  1. 指令的原始碼位置。如果 show_positions 為 true,則顯示完整的位置資訊。否則(預設)只顯示行號。

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

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

  4. 指令的地址,

  5. 操作碼名稱,

  6. 操作引數,以及

  7. 括號中對引數的解釋。

引數解釋能識別區域性和全域性變數名、常量值、分支目標和比較運算子。

如果提供了 file 引數,反彙編結果將作為文字寫入該檔案,否則寫入 sys.stdout

在 3.4 版更改: 添加了 file 引數。

在 3.11 版更改: 添加了 show_cachesadaptive 引數。

在 3.13 版更改: 添加了 show_offsets 引數。

在 3.14 版更改: 添加了 show_positions 引數。

dis.get_instructions(x, *, first_line=None, show_caches=False, adaptive=False)

返回一個迭代器,用於遍歷提供的函式、方法、原始碼字串或程式碼物件中的指令。

迭代器生成一系列 Instruction 命名元組,給出所提供程式碼中每個操作的詳細資訊。

如果 first_line 不為 None,它表示在反彙編程式碼中為第一行原始碼報告的行號。否則,原始碼行資訊(如果有)直接從反彙編的程式碼物件中獲取。

adaptive 引數的作用與在 dis() 中一樣。

在 3.4 版本加入。

在 3.11 版更改: 添加了 show_cachesadaptive 引數。

在 3.13 版更改: show_caches 引數已棄用且不起作用。迭代器會生成填充了 cache_info 欄位的 Instruction 例項(無論 show_caches 的值如何),並且不再為快取條目生成單獨的項。

dis.findlinestarts(code)

這個生成器函式使用 程式碼物件 codeco_lines() 方法來查詢原始碼中行開始的偏移量。它們以 (offset, lineno) 對的形式生成。

在 3.6 版更改: 行號可以遞減。以前,它們總是遞增的。

在 3.10 版更改: 使用了 PEP 626co_lines() 方法,取代了 程式碼物件co_firstlinenoco_lnotab 屬性。

在 3.13 版更改: 對於不對映到原始碼行的位元組碼,行號可以為 None

dis.findlabels(code)

檢測原始編譯位元組碼字串 code 中所有作為跳轉目標的偏移量,並返回這些偏移量的列表。

dis.stack_effect(opcode, oparg=None, *, jump=None)

計算帶引數 opargopcode 的堆疊效應。

如果程式碼有跳轉目標且 jumpTruestack_effect() 將返回跳轉的堆疊效應。如果 jumpFalse,它將返回不跳轉的堆疊效應。如果 jumpNone(預設值),它將返回兩種情況下的最大堆疊效應。

在 3.4 版本加入。

在 3.8 版更改: 添加了 jump 引數。

在 3.13 版更改: 如果省略 oparg(或為 None),現在將返回 oparg=0 的堆疊效應。以前,對於使用引數的操作碼,這會引發錯誤。當 opcode 不使用引數時,傳遞一個整數 oparg 也不再是錯誤;在這種情況下,oparg 會被忽略。

Python 位元組碼指令

get_instructions() 函式和 Bytecode 類以 Instruction 例項的形式提供位元組碼指令的詳細資訊。

class dis.Instruction

位元組碼操作的詳細資訊

opcode

操作的數字程式碼,對應於下面列出的操作碼值和 操作碼集合 中的位元組碼值。

opname

人類可讀的操作名稱

baseopcode

如果操作是特化的,則為基礎操作的數字程式碼;否則等於 opcode

baseopname

如果操作是特化的,則為基礎操作的人類可讀名稱;否則等於 opname

arg

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

oparg

arg 的別名

argval

解析後的引數值(如果有),否則為 None

argrepr

操作引數的人類可讀描述(如果有),否則為空字串。

offset

操作在位元組碼序列中的起始索引

start_offset

操作在位元組碼序列中的起始索引,包括字首的 EXTENDED_ARG 操作(如果存在);否則等於 offset

cache_offset

操作後快取條目的起始索引

end_offset

操作後快取條目的結束索引

starts_line

如果此操作碼開始一個原始碼行,則為 True,否則為 False

line_number

與此操作碼關聯的原始碼行號(如果有),否則為 None

is_jump_target

如果其他程式碼跳轉到此處,則為 True,否則為 False

jump_target

如果這是一個跳轉操作,則為跳轉目標的位元組碼索引,否則為 None

positions

dis.Positions 物件,包含此指令覆蓋的起始和結束位置。

cache_info

關於此指令快取條目的資訊,形式為 (name, size, data) 的三元組,其中 namesize 描述快取格式,data 是快取的內容。如果指令沒有快取,則 cache_infoNone

在 3.4 版本加入。

在 3.11 版更改: 添加了欄位 positions

在 3.13 版更改: 更改了欄位 starts_line

添加了欄位 start_offsetcache_offsetend_offsetbaseopnamebaseopcodejump_targetopargline_numbercache_info

class dis.Positions

如果資訊不可用,某些欄位可能為 None

lineno
end_lineno
col_offset
end_col_offset

在 3.11 版本中新增。

Python 編譯器目前生成以下位元組碼指令。

通用指令

在下文中,我們將直譯器堆疊稱為 STACK,並像操作 Python 列表一樣描述對其的操作。堆疊頂部對應於此語言中的 STACK[-1]

NOP

空操作碼。由位元組碼最佳化器用作佔位符,以及生成行跟蹤事件。

NOT_TAKEN

空操作碼。由直譯器用於為 sys.monitoring 記錄 BRANCH_LEFTBRANCH_RIGHT 事件。

在 3.14 版本加入。

POP_ITER

從堆疊頂部移除迭代器。

在 3.14 版本加入。

POP_TOP

移除棧頂項

STACK.pop()
END_FOR

移除棧頂項。等同於 POP_TOP。用於在迴圈結束時進行清理,因此得名。

3.12 新版功能.

END_SEND

實現 del STACK[-2]。用於在生成器退出時進行清理。

3.12 新版功能.

COPY(i)

將第 i 個項推送到堆疊頂部,而不從其原始位置移除

assert i > 0
STACK.append(STACK[-i])

在 3.11 版本中新增。

SWAP(i)

將堆疊頂部與第 i 個元素交換

STACK[-i], STACK[-1] = STACK[-1], STACK[-i]

在 3.11 版本中新增。

CACHE

與其說這是一個實際的指令,不如說這個操作碼用於標記額外的空間,供直譯器直接在位元組碼中快取有用的資料。它被所有 dis 工具自動隱藏,但可以透過 show_caches=True 檢視。

在邏輯上,這個空間是前一條指令的一部分。許多操作碼期望後面跟著確切數量的快取,並會指示直譯器在執行時跳過它們。

已填充的快取可能看起來像任意指令,因此在讀取或修改包含已加速資料的原始、自適應位元組碼時應格外小心。

在 3.11 版本中新增。

一元操作

一元操作取棧頂元素,應用操作,然後將結果壓回棧中。

UNARY_NEGATIVE

實現 STACK[-1] = -STACK[-1]

UNARY_NOT

實現 STACK[-1] = not STACK[-1]

在 3.13 版更改: 此指令現在需要一個確切的 bool 運算元。

UNARY_INVERT

實現 STACK[-1] = ~STACK[-1]

GET_ITER

實現 STACK[-1] = iter(STACK[-1])

GET_YIELD_FROM_ITER

如果 STACK[-1] 是一個 生成器迭代器協程 物件,它將保持原樣。否則,實現 STACK[-1] = iter(STACK[-1])

在 3.5 版本加入。

TO_BOOL

實現 STACK[-1] = bool(STACK[-1])

在 3.13 版本加入。

二元和原地操作

二元操作從堆疊中移除頂部兩個項(STACK[-1]STACK[-2])。它們執行操作,然後將結果放回堆疊。

原地操作類似於二元操作,但是當 STACK[-2] 支援時,操作是原地進行的,並且最終的 STACK[-1] 可能是(但不必須是)原始的 STACK[-2]

BINARY_OP(op)

實現二元和原地運算子(取決於 op 的值)

rhs = STACK.pop()
lhs = STACK.pop()
STACK.append(lhs op rhs)

在 3.11 版本中新增。

在 3.14 版更改: 當 oparg 為 NB_SUBSCR 時,實現二元下標操作(取代了 BINARY_SUBSCR 操作碼)。

STORE_SUBSCR

實現

key = STACK.pop()
container = STACK.pop()
value = STACK.pop()
container[key] = value
DELETE_SUBSCR

實現

key = STACK.pop()
container = STACK.pop()
del container[key]
BINARY_SLICE

實現

end = STACK.pop()
start = STACK.pop()
container = STACK.pop()
STACK.append(container[start:end])

3.12 新版功能.

STORE_SLICE

實現

end = STACK.pop()
start = STACK.pop()
container = STACK.pop()
values = STACK.pop()
container[start:end] = value

3.12 新版功能.

協程操作碼

GET_AWAITABLE(where)

實現 STACK[-1] = get_awaitable(STACK[-1]),其中 get_awaitable(o)o 是一個協程物件或帶有 CO_ITERABLE_COROUTINE 旗標的生成器物件時會返回 o,或者解析 o.__await__

如果 where 運算元非零,它指示指令發生的位置:

  • 1: 在呼叫 __aenter__ 之後

  • 2: 在呼叫 __aexit__ 之後

在 3.5 版本加入。

在 3.11 版更改: 之前,此指令沒有運算元引數。

GET_AITER

實現 STACK[-1] = STACK[-1].__aiter__()

在 3.5 版本加入。

在 3.7 版更改: 不再支援從 __aiter__ 返回可等待物件。

GET_ANEXT

STACK.append(get_awaitable(STACK[-1].__anext__())) 推入堆疊。有關 get_awaitable 的詳細資訊,請參見 GET_AWAITABLE

在 3.5 版本加入。

END_ASYNC_FOR

終止一個 async for 迴圈。處理在等待下一個項時引發的異常。堆疊在 STACK[-2] 中包含非同步可迭代物件,在 STACK[-1] 中包含引發的異常。兩者都會被彈出。如果異常不是 StopAsyncIteration,則會重新引發。

在 3.8 版本加入。

在 3.11 版更改: 堆疊上的異常表示現在由一個而非三個項組成。

CLEANUP_THROW

處理在通過當前幀呼叫 throw()close() 期間引發的異常。如果 STACK[-1]StopIteration 的例項,則從堆疊中彈出三個值並推送其 value 成員。否則,重新引發 STACK[-1]

3.12 新版功能.

雜項操作碼

SET_ADD(i)

實現

item = STACK.pop()
set.add(STACK[-i], item)

用於實現集合推導式。

LIST_APPEND(i)

實現

item = STACK.pop()
list.append(STACK[-i], item)

用於實現列表推導式。

MAP_ADD(i)

實現

value = STACK.pop()
key = STACK.pop()
dict.__setitem__(STACK[-i], key, value)

用於實現字典推導式。

在 3.1 版本加入。

在 3.8 版更改: 對映的值是 STACK[-1],鍵是 STACK[-2]。以前,這兩者是相反的。

對於所有 SET_ADD, LIST_APPENDMAP_ADD 指令,雖然新增的值或鍵/值對被彈出,但容器物件仍保留在堆疊上,以便在迴圈的後續迭代中可用。

RETURN_VALUE

STACK[-1] 返回給函式的呼叫者。

YIELD_VALUE

生成器 中產生 STACK.pop()

在 3.11 版更改: 運算元引數被設為棧深度。

在 3.12 版更改: 運算元引數被設為異常塊深度,以高效地關閉生成器。

在 3.13 版更改: 如果此指令是 yield-from 或 await 的一部分,則 oparg 為 1,否則為 0

SETUP_ANNOTATIONS

檢查 __annotations__ 是否在 locals() 中定義,如果未定義,則將其設定為空的 dict。僅當類或模組主體靜態包含變數註解時,才會發出此操作碼。

在 3.6 版本加入。

POP_EXCEPT

從堆疊中彈出一個值,用於恢復異常狀態。

在 3.11 版更改: 堆疊上的異常表示現在由一個而非三個項組成。

RERAISE

重新引發當前在棧頂的異常。如果 oparg 非零,則從堆疊中彈出一個額外的值,用於設定當前幀的 f_lasti

在 3.9 版本中新增。

在 3.11 版更改: 堆疊上的異常表示現在由一個而非三個項組成。

PUSH_EXC_INFO

從堆疊中彈出一個值。將當前異常推到堆疊頂部。將最初彈出的值推回堆疊。用於異常處理程式中。

在 3.11 版本中新增。

CHECK_EXC_MATCH

except 執行異常匹配。測試 STACK[-2] 是否是與 STACK[-1] 匹配的異常。彈出 STACK[-1] 並推送測試的布林結果。

在 3.11 版本中新增。

CHECK_EG_MATCH

except* 執行異常匹配。在表示 STACK[-2] 的異常組上應用 split(STACK[-1])

如果匹配,則從堆疊中彈出兩個項,並推送不匹配的子組(如果完全匹配則為 None),後跟匹配的子組。如果不匹配,則彈出一個項(匹配型別)並推送 None

在 3.11 版本中新增。

WITH_EXCEPT_START

使用表示棧頂異常的引數 (type, val, tb) 呼叫堆疊中位置 4 的函式。用於在 with 語句中發生異常時,實現 context_manager.__exit__(*exc_info()) 呼叫。

在 3.9 版本中新增。

在 3.11 版更改: __exit__ 函式位於堆疊的第 4 位,而不是第 7 位。堆疊上的異常表示現在由一個而非三個項組成。

LOAD_COMMON_CONSTANT

將一個通用常量推入堆疊。直譯器包含一個硬編碼的此指令支援的常量列表。由 assert 語句用於載入 AssertionError

在 3.14 版本加入。

LOAD_BUILD_CLASS

builtins.__build_class__() 推入堆疊。稍後會呼叫它來構造一個類。

GET_LEN

執行 STACK.append(len(STACK[-1]))。用於需要與模式結構進行比較的 match 語句中。

在 3.10 版本加入。

MATCH_MAPPING

如果 STACK[-1]collections.abc.Mapping 的例項(或者,更技術性地說:如果它的 tp_flags 中設定了 Py_TPFLAGS_MAPPING 標誌),則將 True 推入堆疊。否則,推送 False

在 3.10 版本加入。

MATCH_SEQUENCE

如果 STACK[-1]collections.abc.Sequence 的例項並且*不是* str/bytes/bytearray 的例項(或者,更技術性地說:如果它的 tp_flags 中設定了 Py_TPFLAGS_SEQUENCE 標誌),則將 True 推入堆疊。否則,推送 False

在 3.10 版本加入。

MATCH_KEYS

STACK[-1] 是一個對映鍵的元組,而 STACK[-2] 是匹配的主體。如果 STACK[-2] 包含 STACK[-1] 中的所有鍵,則推送一個包含相應值的 tuple。否則,推送 None

在 3.10 版本加入。

在 3.11 版更改: 以前,此指令還會推送一個布林值來表示成功(True)或失敗(False)。

STORE_NAME(namei)

實現 name = STACK.pop()nameiname程式碼物件co_names 屬性中的索引。編譯器會嘗試儘可能使用 STORE_FASTSTORE_GLOBAL

DELETE_NAME(namei)

實現 del name,其中 nameiname程式碼物件co_names 屬性中的索引。

UNPACK_SEQUENCE(count)

STACK[-1] 解包為 count 個單獨的值,這些值從右到左放入堆疊。要求值的數量恰好為 count

assert(len(STACK[-1]) == count)
STACK.extend(STACK.pop()[:-count-1:-1])
UNPACK_EX(counts)

實現帶星號目標的賦值:將 STACK[-1] 中的可迭代物件解包為單獨的值,其中值的總數可以小於可迭代物件中的項數:其中一個新值將是所有剩餘項的列表。

列表值之前和之後的值的數量限制為 255。

列表值之前的值的數量編碼在操作碼的引數中。列表之後的值的數量(如果有)使用 EXTENDED_ARG 進行編碼。因此,該引數可以看作一個兩位元組的值,其中 counts 的低位元組是列表值之前的值的數量,counts 的高位元組是列表之後的值的數量。

提取的值從右到左放入堆疊,即 a, *b, c = d 在執行後將儲存為 STACK.extend((a, b, c))

STORE_ATTR(namei)

實現

obj = STACK.pop()
value = STACK.pop()
obj.name = value

其中 nameiname程式碼物件co_names 中的索引。

DELETE_ATTR(namei)

實現

obj = STACK.pop()
del obj.name

其中 nameiname程式碼物件co_names 中的索引。

STORE_GLOBAL(namei)

作用類似於 STORE_NAME,但將名稱儲存為全域性變數。

DELETE_GLOBAL(namei)

作用類似於 DELETE_NAME,但刪除一個全域性名稱。

LOAD_CONST(consti)

co_consts[consti] 推入堆疊。

LOAD_SMALL_INT(i)

將整數 i 推入堆疊。i 必須在 range(256) 範圍內。

在 3.14 版本加入。

LOAD_NAME(namei)

將與 co_names[namei] 關聯的值推入堆疊。該名稱會先在區域性變數中查詢,然後在全域性變數中查詢,最後在內建變數中查詢。

LOAD_LOCALS

將對區域性變數字典的引用推入堆疊。這用於為 LOAD_FROM_DICT_OR_DEREFLOAD_FROM_DICT_OR_GLOBALS 準備名稱空間字典。

3.12 新版功能.

LOAD_FROM_DICT_OR_GLOBALS(i)

從堆疊中彈出一個對映,並查詢 co_names[namei] 的值。如果未找到該名稱,則在全域性變數中查詢,然後在內建變數中查詢,類似於 LOAD_GLOBAL。這用於在類主體內的 註解作用域 中載入全域性變數。

3.12 新版功能.

BUILD_TEMPLATE

從一個字串元組和一個插值元組構造一個新的 Template 例項,並將生成的物件推入堆疊

interpolations = STACK.pop()
strings = STACK.pop()
STACK.append(_build_template(strings, interpolations))

在 3.14 版本加入。

BUILD_INTERPOLATION(format)

從一個值及其源表示式構造一個新的 Interpolation 例項,並將生成的物件推入堆疊。

如果沒有轉換或格式說明符,format 將設定為 2

如果 format 的低位被設定,表示插值包含格式說明符。

如果 format >> 2 非零,表示插值包含轉換。format >> 2 的值是轉換型別(0 表示無轉換,1 表示 !s2 表示 !r3 表示 !a)。

conversion = format >> 2
if format & 1:
    format_spec = STACK.pop()
else:
    format_spec = None
expression = STACK.pop()
value = STACK.pop()
STACK.append(_build_interpolation(value, expression, conversion, format_spec))

在 3.14 版本加入。

BUILD_TUPLE(count)

從棧中消費 count 個項來建立一個元組,並將結果元組推入棧中。

if count == 0:
    value = ()
else:
    value = tuple(STACK[-count:])
    STACK = STACK[:-count]

STACK.append(value)
BUILD_LIST(count)

工作方式類似 BUILD_TUPLE,但是建立一個列表。

BUILD_SET(count)

工作方式類似 BUILD_TUPLE,但是建立一個集合。

BUILD_MAP(count)

將一個新的字典物件推入棧中。彈出 2 * count 個項,使得該字典包含 count 個條目:{..., STACK[-4]: STACK[-3], STACK[-2]: STACK[-1]}

在 3.5 版本發生變更: 字典從棧中的項建立,而不是建立一個預設大小為 count 的空字典。

BUILD_STRING(count)

拼接棧中的 count 個字串,並將結果字串推入棧中。

在 3.6 版本加入。

LIST_EXTEND(i)

實現

seq = STACK.pop()
list.extend(STACK[-i], seq)

用於構建列表。

在 3.9 版本中新增。

SET_UPDATE(i)

實現

seq = STACK.pop()
set.update(STACK[-i], seq)

用於構建集合。

在 3.9 版本中新增。

DICT_UPDATE(i)

實現

map = STACK.pop()
dict.update(STACK[-i], map)

用於構建字典。

在 3.9 版本中新增。

DICT_MERGE(i)

類似於 DICT_UPDATE,但對於重複的鍵會引發異常。

在 3.9 版本中新增。

LOAD_ATTR(namei)

如果 namei 的最低位未設定,此指令會用 getattr(STACK[-1], co_names[namei>>1]) 替換 STACK[-1]

如果 namei 的最低位已設定,此指令將嘗試從 STACK[-1] 物件載入名為 co_names[namei>>1] 的方法。STACK[-1] 會被彈出。此位元組碼區分兩種情況:如果 STACK[-1] 具有正確名稱的方法,位元組碼會推入未繫結方法和 STACK[-1]STACK[-1] 將被 CALLCALL_KW 用作呼叫未繫結方法時的第一個引數 (self)。否則,會將 NULL 和屬性查詢返回的物件推入棧中。

在 3.12 版本發生變更: 如果 namei 的最低位已設定,則會在屬性或未繫結方法之前分別向棧中推入一個 NULLself

LOAD_SUPER_ATTR(namei)

此操作碼實現了 super() 的兩種形式:零引數和雙引數(例如 super().method(), super().attrsuper(cls, self).method(), super(cls, self).attr)。

它從棧中彈出三個值(從棧頂向下):

  • self:當前方法的第一個引數

  • cls:定義當前方法的類

  • 全域性的 super

就其引數而言,它的工作方式類似於 LOAD_ATTR,只是 namei 左移 2 位而不是 1 位。

namei 的最低位表示嘗試載入方法,與 LOAD_ATTR 一樣,這會導致將 NULL 和載入的方法推入棧中。當它未設定時,會將單個值推入棧中。

如果 namei 的次低位被設定,則表示這是一個對 super() 的雙引數呼叫(未設定則表示零引數)。

3.12 新版功能.

COMPARE_OP(opname)

執行布林運算。運算名稱可以在 cmp_op[opname >> 5] 中找到。如果 opname 的第五個最低位被設定 (opname & 16),則結果應被強制轉換為 bool

在 3.13 版本發生變更: oparg 的第五個最低位現在表示強制轉換為 bool

IS_OP(invert)

執行 is 比較,如果 invert 為 1 則執行 is not

在 3.9 版本中新增。

CONTAINS_OP(invert)

執行 in 比較,如果 invert 為 1 則執行 not in

在 3.9 版本中新增。

IMPORT_NAME(namei)

匯入模組 co_names[namei]STACK[-1]STACK[-2] 被彈出並提供 __import__()fromlistlevel 引數。模組物件被推入棧中。當前名稱空間不受影響:對於一個正確的匯入語句,後續的 STORE_FAST 指令會修改名稱空間。

IMPORT_FROM(namei)

STACK[-1] 中的模組載入屬性 co_names[namei]。結果物件被推入棧中,隨後由 STORE_FAST 指令儲存。

JUMP_FORWARD(delta)

位元組碼計數器增加 delta

JUMP_BACKWARD(delta)

位元組碼計數器減少 delta。檢查中斷。

在 3.11 版本中新增。

JUMP_BACKWARD_NO_INTERRUPT(delta)

位元組碼計數器減少 delta。不檢查中斷。

在 3.11 版本中新增。

POP_JUMP_IF_TRUE(delta)

如果 STACK[-1] 為真,位元組碼計數器增加 deltaSTACK[-1] 被彈出。

在 3.11 版本發生變更: oparg 現在是一個相對增量,而不是一個絕對目標。此操作碼是一個偽指令,在最終位元組碼中被定向版本(前向/後向)替換。

在 3.12 版本發生變更: 這不再是偽指令。

在 3.13 版更改: 此指令現在需要一個確切的 bool 運算元。

POP_JUMP_IF_FALSE(delta)

如果 STACK[-1] 為假,位元組碼計數器增加 deltaSTACK[-1] 被彈出。

在 3.11 版本發生變更: oparg 現在是一個相對增量,而不是一個絕對目標。此操作碼是一個偽指令,在最終位元組碼中被定向版本(前向/後向)替換。

在 3.12 版本發生變更: 這不再是偽指令。

在 3.13 版更改: 此指令現在需要一個確切的 bool 運算元。

POP_JUMP_IF_NOT_NONE(delta)

如果 STACK[-1] 不是 None,位元組碼計數器增加 deltaSTACK[-1] 被彈出。

在 3.11 版本中新增。

在 3.12 版本發生變更: 這不再是偽指令。

POP_JUMP_IF_NONE(delta)

如果 STACK[-1]None,位元組碼計數器增加 deltaSTACK[-1] 被彈出。

在 3.11 版本中新增。

在 3.12 版本發生變更: 這不再是偽指令。

FOR_ITER(delta)

STACK[-1] 是一個迭代器。呼叫其 __next__() 方法。如果這產生了一個新值,則將其推入棧中(迭代器保留在它下面)。如果迭代器表示已耗盡,則位元組碼計數器增加 delta

在 3.12 版本發生變更: 在 3.11 之前,當迭代器耗盡時會被彈出。

LOAD_GLOBAL(namei)

將名為 co_names[namei>>1] 的全域性變數載入到棧上。

在 3.11 版本發生變更: 如果 namei 的最低位被設定,則在全域性變數之前將一個 NULL 推入棧中。

LOAD_FAST(var_num)

將區域性變數 co_varnames[var_num] 的引用推入棧中。

在 3.12 版本發生變更: 此操作碼現在僅用於區域性變數保證已初始化的情況。它不會引發 UnboundLocalError

LOAD_FAST_BORROW(var_num)

將區域性變數 co_varnames[var_num] 的借用引用推入棧中。

在 3.14 版本加入。

LOAD_FAST_LOAD_FAST(var_nums)

co_varnames[var_nums >> 4]co_varnames[var_nums & 15] 的引用推入棧中。

在 3.13 版本加入。

LOAD_FAST_BORROW_LOAD_FAST_BORROW(var_nums)

co_varnames[var_nums >> 4]co_varnames[var_nums & 15] 的借用引用推入棧中。

在 3.14 版本加入。

LOAD_FAST_CHECK(var_num)

將區域性變數 co_varnames[var_num] 的引用推入棧中,如果該區域性變數尚未初始化,則引發 UnboundLocalError

3.12 新版功能.

LOAD_FAST_AND_CLEAR(var_num)

將區域性變數 co_varnames[var_num] 的引用推入棧中(如果該區域性變數尚未初始化,則推入 NULL),並將 co_varnames[var_num] 設定為 NULL

3.12 新版功能.

STORE_FAST(var_num)

STACK.pop() 存入區域性變數 co_varnames[var_num]

STORE_FAST_STORE_FAST(var_nums)

STACK[-1] 存入 co_varnames[var_nums >> 4],將 STACK[-2] 存入 co_varnames[var_nums & 15]

在 3.13 版本加入。

STORE_FAST_LOAD_FAST(var_nums)

STACK.pop() 存入區域性變數 co_varnames[var_nums >> 4],並將區域性變數 co_varnames[var_nums & 15] 的引用推入棧中。

在 3.13 版本加入。

DELETE_FAST(var_num)

刪除區域性變數 co_varnames[var_num]

MAKE_CELL(i)

在槽位 i 建立一個新的單元。如果該槽位非空,則該值將被存入新的單元中。

在 3.11 版本中新增。

LOAD_DEREF(i)

載入“快速區域性變數”儲存區中槽位 i 的單元。將對該單元所含物件的引用推入棧中。

在 3.11 版本發生變更: i 不再透過 co_varnames 的長度進行偏移。

LOAD_FROM_DICT_OR_DEREF(i)

從棧中彈出一個對映,並在該對映中查詢與“快速區域性變數”儲存區槽位 i 相關聯的名稱。如果在那裡找不到該名稱,則從槽位 i 中包含的單元載入它,類似於 LOAD_DEREF。這用於在類主體中(以前使用 LOAD_CLASSDEREF)和類主體內的 註解作用域 中載入 閉包變數

3.12 新版功能.

STORE_DEREF(i)

STACK.pop() 存入“快速區域性變數”儲存區中槽位 i 的單元中。

在 3.11 版本發生變更: i 不再透過 co_varnames 的長度進行偏移。

DELETE_DEREF(i)

清空“快速區域性變數”儲存區中槽位 i 的單元。由 del 語句使用。

在 3.2 版本加入。

在 3.11 版本發生變更: i 不再透過 co_varnames 的長度進行偏移。

COPY_FREE_VARS(n)

從閉包中將 n自由(閉包)變數 複製到幀中。在呼叫閉包時,無需在呼叫方一側使用特殊程式碼。

在 3.11 版本中新增。

RAISE_VARARGS(argc)

根據 argc 的值,使用 raise 語句的三種形式之一引發異常:

  • 0: raise (重新引發前一個異常)

  • 1: raise STACK[-1] (引發在 STACK[-1] 的異常例項或型別)

  • 2: raise STACK[-2] from STACK[-1] (引發在 STACK[-2] 的異常例項或型別,並將 __cause__ 設定為 STACK[-1])

CALL(argc)

使用由 argc 指定的引數數量呼叫一個可呼叫物件。棧上的內容為(按升序排列):

  • 可呼叫物件

  • selfNULL

  • 其餘的位置引數

argc 是位置引數的總數,不包括 self

CALL 從棧中彈出所有引數和可呼叫物件,用這些引數呼叫該可呼叫物件,並將可呼叫物件返回的返回值推入棧中。

在 3.11 版本中新增。

在 3.13 版本發生變更: 可呼叫物件現在總是在棧的相同位置出現。

在 3.13 版本發生變更: 帶關鍵字引數的呼叫現在由 CALL_KW 處理。

CALL_KW(argc)

使用由 argc 指定的引數數量呼叫一個可呼叫物件,包括一個或多個命名引數。棧上的內容為(按升序排列):

  • 可呼叫物件

  • selfNULL

  • 其餘的位置引數

  • 命名引數

  • 一個包含關鍵字引數名稱的 tuple

argc 是位置引數和命名引數的總數,不包括 self。關鍵字引數名稱元組的長度是命名引數的數量。

CALL_KW 從棧中彈出所有引數、關鍵字名稱和可呼叫物件,用這些引數呼叫該可呼叫物件,並將可呼叫物件返回的返回值推入棧中。

在 3.13 版本加入。

CALL_FUNCTION_EX(flags)

使用可變數量的位置引數和關鍵字引數呼叫一個可呼叫物件。如果 flags 的最低位被設定,則棧頂包含一個對映物件,其中包含額外的關鍵字引數。在呼叫可呼叫物件之前,對映物件和可迭代物件分別被“解包”,其內容作為關鍵字引數和位置引數傳入。CALL_FUNCTION_EX 從棧中彈出所有引數和可呼叫物件,用這些引數呼叫該可呼叫物件,並將可呼叫物件返回的返回值推入棧中。

在 3.6 版本加入。

PUSH_NULL

將一個 NULL 推入棧中。在呼叫序列中使用,以匹配非方法呼叫時由 LOAD_METHOD 推入的 NULL

在 3.11 版本中新增。

MAKE_FUNCTION

根據 STACK[-1] 處的程式碼物件構建一個新的函式物件,並將其推入棧中。

在 3.10 版本發生變更: 標誌值 0x04 是一個字串元組,而不是字典。

在 3.11 版本發生變更: 移除了 STACK[-1] 處的限定名稱。

在 3.13 版本發生變更: 移除了棧上由 oparg 標誌表示的額外函式屬性。它們現在使用 SET_FUNCTION_ATTRIBUTE

SET_FUNCTION_ATTRIBUTE(flag)

在函式物件上設定一個屬性。期望函式在 STACK[-1],要設定的屬性值在 STACK[-2];消耗兩者並在 STACK[-1] 留下函式。標誌決定要設定哪個屬性:

  • 0x01 一個包含僅限位置和位置或關鍵字引數的預設值的元組,按位置順序排列

  • 0x02 一個包含僅關鍵字引數預設值的字典

  • 0x04 一個包含引數註解的字串元組

  • 0x08 一個包含自由變數單元的元組,用於建立閉包

在 3.13 版本加入。

BUILD_SLICE(argc)

將一個切片物件推入棧中。argc 必須是 2 或 3。如果是 2,則實現

end = STACK.pop()
start = STACK.pop()
STACK.append(slice(start, end))

如果是 3,則實現

step = STACK.pop()
end = STACK.pop()
start = STACK.pop()
STACK.append(slice(start, end, step))

有關更多資訊,請參閱內建函式 slice()

EXTENDED_ARG(ext)

為任何引數過大而無法放入預設一個位元組的操作碼新增字首。ext 持有一個額外的位元組,作為引數的高位。對於每個操作碼,最多允許三個字首 EXTENDED_ARG,形成一個從兩位元組到四位元組的引數。

CONVERT_VALUE(oparg)

根據 oparg 將值轉換為字串

value = STACK.pop()
result = func(value)
STACK.append(result)
  • oparg == 1:在 value 上呼叫 str()

  • oparg == 2:在 value 上呼叫 repr()

  • oparg == 3:在 value 上呼叫 ascii()

用於實現格式化字串字面量(f-strings)。

在 3.13 版本加入。

FORMAT_SIMPLE

格式化棧頂的值

value = STACK.pop()
result = value.__format__("")
STACK.append(result)

用於實現格式化字串字面量(f-strings)。

在 3.13 版本加入。

FORMAT_WITH_SPEC

使用給定的格式說明符格式化給定的值

spec = STACK.pop()
value = STACK.pop()
result = value.__format__(spec)
STACK.append(result)

用於實現格式化字串字面量(f-strings)。

在 3.13 版本加入。

MATCH_CLASS(count)

STACK[-1] 是一個關鍵字屬性名稱的元組,STACK[-2] 是被匹配的類,STACK[-3] 是匹配的主體。count 是位置子模式的數量。

彈出 STACK[-1], STACK[-2]STACK[-3]。如果 STACK[-3]STACK[-2] 的例項,並且具有 countSTACK[-1] 所要求的位置和關鍵字屬性,則推入一個包含提取屬性的元組。否則,推入 None

在 3.10 版本加入。

在 3.11 版更改: 以前,此指令還會推送一個布林值來表示成功(True)或失敗(False)。

RESUME(context)

一個空操作。執行內部跟蹤、除錯和最佳化檢查。

context 運算元由兩部分組成。最低兩位表示 RESUME 發生的位置:

  • 0 函式的開始,該函式既不是生成器、協程,也不是非同步生成器

  • 1yield 表示式之後

  • 2yield from 表示式之後

  • 3await 表示式之後

如果 RESUME 處於異常深度 1,則下一位為 1,否則為 0

在 3.11 版本中新增。

在 3.13 版本發生變更: oparg 的值已更改,以包含有關異常深度的資訊。

RETURN_GENERATOR

從當前幀建立一個生成器、協程或非同步生成器。用作上述可呼叫物件的程式碼物件中的第一個操作碼。清除當前幀並返回新建立的生成器。

在 3.11 版本中新增。

SEND(delta)

等價於 STACK[-1] = STACK[-2].send(STACK[-1])。用於 yield fromawait 語句。

如果呼叫引發 StopIteration,則從棧中彈出頂部值,推入異常的 value 屬性,並將位元組碼計數器增加 delta

在 3.11 版本中新增。

HAVE_ARGUMENT

這實際上不是一個操作碼。它標識了在 [0,255] 範圍內的操作碼中,不使用其引數的操作碼和使用其引數的操作碼(分別為 < HAVE_ARGUMENT>= HAVE_ARGUMENT)之間的分界線。

如果你的應用程式使用偽指令或專門指令,請改用 hasarg 集合。

在 3.6 版本發生變更: 現在每個指令都有一個引數,但 < HAVE_ARGUMENT 的操作碼會忽略它。在此之前,只有 >= HAVE_ARGUMENT 的操作碼有引數。

在 3.12 版本發生變更: 偽指令已新增到 dis 模組中,對於它們來說,與 HAVE_ARGUMENT 比較並不能表明它們是否使用其引數。

自 3.13 版本起棄用: 請改用 hasarg

CALL_INTRINSIC_1

呼叫一個帶有一個引數的內建函式。將 STACK[-1] 作為引數傳遞,並將 STACK[-1] 設定為結果。用於實現非效能關鍵的功能。

運算元決定呼叫哪個內建函式:

運算元

描述

INTRINSIC_1_INVALID

無效

INTRINSIC_PRINT

將引數列印到標準輸出。在 REPL 中使用。

INTRINSIC_IMPORT_STAR

為指定模組執行 import *

INTRINSIC_STOPITERATION_ERROR

StopIteration 異常中提取返回值。

INTRINSIC_ASYNC_GEN_WRAP

包裝一個非同步生成器值

INTRINSIC_UNARY_POSITIVE

執行一元 + 運算

INTRINSIC_LIST_TO_TUPLE

將列表轉換為元組

INTRINSIC_TYPEVAR

建立一個 typing.TypeVar

INTRINSIC_PARAMSPEC

建立一個 typing.ParamSpec

INTRINSIC_TYPEVARTUPLE

建立一個 typing.TypeVarTuple

INTRINSIC_SUBSCRIPT_GENERIC

返回用引數下標化的 typing.Generic

INTRINSIC_TYPEALIAS

建立一個 typing.TypeAliasType;用於 type 語句。引數是一個包含類型別名名稱、型別引數和值的元組。

3.12 新版功能.

CALL_INTRINSIC_2

呼叫一個帶有兩個引數的內建函式。用於實現非效能關鍵的功能:

arg2 = STACK.pop()
arg1 = STACK.pop()
result = intrinsic2(arg1, arg2)
STACK.append(result)

運算元決定呼叫哪個內建函式:

運算元

描述

INTRINSIC_2_INVALID

無效

INTRINSIC_PREP_RERAISE_STAR

計算從 try-except* 中要引發的 ExceptionGroup

INTRINSIC_TYPEVAR_WITH_BOUND

建立一個帶有邊界的 typing.TypeVar

INTRINSIC_TYPEVAR_WITH_CONSTRAINTS

建立一個帶有約束的 typing.TypeVar

INTRINSIC_SET_FUNCTION_TYPE_PARAMS

設定函式的 __type_params__ 屬性。

3.12 新版功能.

LOAD_SPECIAL

STACK[-1] 上執行特殊方法查詢。如果 type(STACK[-1]).__xxx__ 是一個方法,則將 type(STACK[-1]).__xxx__; STACK[-1] 留在棧上。如果 type(STACK[-1]).__xxx__ 不是一個方法,則將 STACK[-1].__xxx__; NULL 留在棧上。

在 3.14 版本加入。

偽指令

這些操作碼不會出現在 Python 位元組碼中。它們被編譯器使用,但在生成位元組碼之前被替換為真正的操作碼或被移除。

SETUP_FINALLY(target)

為接下來的程式碼塊設定一個異常處理程式。如果發生異常,值棧的層級將恢復到當前狀態,並且控制權將轉移到 target 處的異常處理程式。

SETUP_CLEANUP(target)

類似於 SETUP_FINALLY,但在發生異常時還會將最後一條指令 (lasti) 推入棧中,以便 RERAISE 可以恢復它。如果發生異常,值棧的層級和幀上的最後一條指令將恢復到當前狀態,並且控制權將轉移到 target 處的異常處理程式。

SETUP_WITH(target)

類似於 SETUP_CLEANUP,但在發生異常時,在將控制權轉移到 target 處的異常處理程式之前,會從棧中再彈出一個項。

這個變體用於 withasync with 結構中,它們會將上下文管理器的 __enter__()__aenter__() 的返回值推入棧中。

POP_BLOCK

標記與最後一個 SETUP_FINALLYSETUP_CLEANUPSETUP_WITH 相關聯的程式碼塊的結束。

LOAD_CONST_IMMORTAL(consti)

工作方式類似 LOAD_CONST,但對於不朽物件更高效。

JUMP
JUMP_NO_INTERRUPT

非定向的相對跳轉指令,由彙編器替換為其定向(前向/後向)的對應指令。

JUMP_IF_TRUE
JUMP_IF_FALSE

不影響棧的條件跳轉。被替換為序列 COPY 1TO_BOOLPOP_JUMP_IF_TRUE/FALSE

LOAD_CLOSURE(i)

將“快速區域性變數”儲存區中槽位 i 所含單元的引用推入棧中。

請注意,LOAD_CLOSURE 在彙編器中被替換為 LOAD_FAST

在 3.13 版本發生變更: 此操作碼現在是一個偽指令。

操作碼集合

提供這些集合是為了對位元組碼指令進行自動內省:

在 3.12 版本發生變更: 這些集合現在也包含偽指令和被插樁的指令。這些是值 >= MIN_PSEUDO_OPCODE>= MIN_INSTRUMENTED_OPCODE 的操作碼。

dis.opname

操作名稱序列,可使用位元組碼進行索引。

dis.opmap

將操作名稱對映到位元組碼的字典。

dis.cmp_op

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

dis.hasarg

使用其引數的位元組碼序列。

3.12 新版功能.

dis.hasconst

訪問常量的位元組碼序列。

dis.hasfree

訪問自由(閉包)變數的位元組碼序列。此處的 'free' 指的是當前作用域中被內部作用域引用的名稱,或外部作用域中被此作用域引用的名稱。它 包括對全域性或內建作用域的引用。

dis.hasname

透過名稱訪問屬性的位元組碼序列。

dis.hasjump

具有跳轉目標的位元組碼序列。所有跳轉都是相對的。

在 3.13 版本加入。

dis.haslocal

訪問區域性變數的位元組碼序列。

dis.hascompare

布林運算的位元組碼序列。

dis.hasexc

設定異常處理程式的位元組碼序列。

3.12 新版功能.

dis.hasjrel

具有相對跳轉目標的位元組碼序列。

自 3.13 版本起棄用: 現在所有跳轉都是相對的。請使用 hasjump

dis.hasjabs

具有絕對跳轉目標的位元組碼序列。

自 3.13 版本起棄用: 現在所有跳轉都是相對的。此列表為空。