dis --- Python 字节码反汇编器

Source code: Lib/dis.py


dis 模块通过反汇编支持CPython的 bytecode 分析。该模块作为输入的 CPython 字节码在文件 Include/opcode.h 中定义,并由编译器和解释器使用。

CPython 实现细节: 字节码是 CPython 解释器的实现细节。不保证不会在Python版本之间添加、删除或更改字节码。不应考虑将此模块的跨 Python VM 或 Python 版本的使用。

在 3.6 版更改: 每条指令使用2个字节。以前字节数因指令而异。

在 3.10 版更改: The argument of jump, exception handling and loop instructions is now the instruction offset rather than the byte offset.

在 3.11 版更改: Some instructions are accompanied by one or more inline cache entries, which take the form of CACHE instructions. These instructions are hidden by default, but can be shown by passing show_caches=True to any dis utility. Furthermore, the interpreter now adapts the bytecode to specialize it for different runtime conditions. The adaptive bytecode can be shown by passing adaptive=True.

示例:给出函数 myfunc():

def myfunc(alist):
    return len(alist)

the following command can be used to display the disassembly of myfunc():

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

  3           2 LOAD_GLOBAL              1 (NULL + len)
             14 LOAD_FAST                0 (alist)
             16 PRECALL                  1
             20 CALL                     1
             30 RETURN_VALUE

("2" 是行号)。

字节码分析

3.4 新版功能.

字节码分析 API 允许将 Python 代码片段包装在 Bytecode 对象中,以便轻松访问已编译代码的详细信息。

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

分析的字节码对应于函数、生成器、异步生成器、协程、方法、源代码字符串或代码对象(由 compile() 返回)。

这是下面列出的许多函数的便利包装,最值得注意的是 get_instructions() ,迭代于 Bytecode 的实例产生字节码操作 Instruction 的实例。

如果 first_line 不是 None ,则表示应该为反汇编代码中的第一个源代码行报告的行号。否则,源行信息(如果有的话)直接来自反汇编的代码对象。

如果 current_offset 不是 None ,则它指的是反汇编代码中的指令偏移量。设置它意味着 dis() 将针对指定的操作码显示“当前指令”标记。

If show_caches is True, dis() will display inline cache entries used by the interpreter to specialize the bytecode.

If adaptive is True, dis() will display specialized bytecode that may be different from the original bytecode.

classmethod from_traceback(tb, *, show_caches=False)

从给定回溯构造一个 Bytecode 实例,将设置 current_offset 为异常负责的指令。

codeobj

已编译的代码对象。

first_line

代码对象的第一个源代码行(如果可用)

dis()

返回字节码操作的格式化视图(与 dis.dis() 打印相同,但作为多行字符串返回)。

info()

返回带有关于代码对象的详细信息的格式化多行字符串,如 code_info()

在 3.7 版更改: 现在可以处理协程和异步生成器对象。

在 3.11 版更改: Added the show_caches and adaptive parameters.

Example:

>>> bytecode = dis.Bytecode(myfunc)
>>> for instr in bytecode:
...     print(instr.opname)
...
RESUME
LOAD_GLOBAL
LOAD_FAST
PRECALL
CALL
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, show_caches=False, adaptive=False)

反汇编 x 对象。 x 可以表示模块、类、方法、函数、生成器、异步生成器、协程、代码对象、源代码字符串或原始字节码的字节序列。对于模块,它会反汇编所有功能。对于一个类,它反汇编所有方法(包括类和静态方法)。对于代码对象或原始字节码序列,它每字节码指令打印一行。它还递归地反汇编嵌套代码对象(推导式代码,生成器表达式和嵌套函数,以及用于构建嵌套类的代码)。在被反汇编之前,首先使用 compile() 内置函数将字符串编译为代码对象。如果未提供任何对象,则此函数会反汇编最后一次回溯。

如果提供的话,反汇编将作为文本写入提供的 file 参数,否则写入 sys.stdout

递归的最大深度受 depth 限制,除非它是 Nonedepth=0 表示没有递归。

If show_caches is True, this function will display inline cache entries used by the interpreter to specialize the bytecode.

If adaptive is True, this function will display specialized bytecode that may be different from the original bytecode.

在 3.4 版更改: 添加 file 形参。

在 3.7 版更改: 实现了递归反汇编并添加了 depth 参数。

在 3.7 版更改: 现在可以处理协程和异步生成器对象。

在 3.11 版更改: Added the show_caches and adaptive parameters.

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

如果没有传递,则使用最后一个回溯来反汇编回溯的堆栈顶部函数。 指示了导致异常的指令。

如果提供的话,反汇编将作为文本写入提供的 file 参数,否则写入 sys.stdout

在 3.4 版更改: 添加 file 形参。

在 3.11 版更改: Added the show_caches and adaptive parameters.

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

反汇编代码对象,如果提供了 lasti ,则指示最后一条指令。输出分为以下几列:

  1. 行号,用于每行的第一条指令

  2. 当前指令,表示为 -->

  3. 一个标记的指令,用 >> 表示,

  4. 指令的地址,

  5. 操作码名称,

  6. 操作参数,和

  7. 括号中参数的解释。

参数解释识别本地和全局变量名称、常量值、分支目标和比较运算符。

如果提供的话,反汇编将作为文本写入提供的 file 参数,否则写入 sys.stdout

在 3.4 版更改: 添加 file 形参。

在 3.11 版更改: Added the show_caches and adaptive parameters.

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

在所提供的函数、方法、源代码字符串或代码对象中的指令上返回一个迭代器。

迭代器生成一系列 Instruction ,命名为元组,提供所提供代码中每个操作的详细信息。

如果 first_line 不是 None ,则表示应该为反汇编代码中的第一个源代码行报告的行号。否则,源行信息(如果有的话)直接来自反汇编的代码对象。

The show_caches and adaptive parameters work as they do in dis().

3.4 新版功能.

在 3.11 版更改: Added the show_caches and adaptive parameters.

dis.findlinestarts(code)

This generator function uses the co_lines method of the code object code to find the offsets which are starts of lines in the source code. They are generated as (offset, lineno) pairs.

在 3.6 版更改: 行号可能会减少。 以前,他们总是在增加。

在 3.10 版更改: The PEP 626 co_lines method is used instead of the co_firstlineno and co_lnotab attributes of the code object.

dis.findlabels(code)

检测作为跳转目标的原始编译后字节码字符串 code 中的所有偏移量,并返回这些偏移量的列表。

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

使用参数 oparg 计算 opcode 的堆栈效果。

如果代码有一个跳转目标并且 jumpTrue ,则 drag_effect() 将返回跳转的堆栈效果。如果 jumpFalse ,它将返回不跳跃的堆栈效果。如果 jumpNone (默认值),它将返回两种情况的最大堆栈效果。

3.4 新版功能.

在 3.8 版更改: 添加 jump 参数。

Python字节码说明

get_instructions() 函数和 Bytecode 类提供字节码指令的详细信息的 Instruction 实例:

class dis.Instruction

字节码操作的详细信息

opcode

操作的数字代码,对应于下面列出的操作码值和 操作码集合 中的字节码值。

opname

人类可读的操作名称

arg

操作的数字参数(如果有的话),否则为 None

argval

resolved arg value (if any), otherwise None

argrepr

human readable description of operation argument (if any), otherwise an empty string.

offset

在字节码序列中启动操作索引

starts_line

行由此操作码(如果有)启动,否则为 None

is_jump_target

如果其他代码跳到这里,则为 True ,否则为 False

positions

dis.Positions object holding the start and end locations that are covered by this instruction.

3.4 新版功能.

在 3.11 版更改: Field positions is added.

class dis.Positions

In case the information is not available, some fields might be None.

lineno
end_lineno
col_offset
end_col_offset

3.11 新版功能.

Python编译器当前生成以下字节码指令。

一般指令

NOP

Do nothing code. Used as a placeholder by the bytecode optimizer, and to generate line tracing events.

POP_TOP

删除堆栈顶部(TOS)项。

COPY(i)

Push the i-th item to the top of the stack. The item is not removed from its original location.

3.11 新版功能.

SWAP(i)

Swap TOS with the item at position i.

3.11 新版功能.

CACHE

Rather than being an actual instruction, this opcode is used to mark extra space for the interpreter to cache useful data directly in the bytecode itself. It is automatically hidden by all dis utilities, but can be viewed with show_caches=True.

Logically, this space is part of the preceding instruction. Many opcodes expect to be followed by an exact number of caches, and will instruct the interpreter to skip over them at runtime.

Populated caches can look like arbitrary instructions, so great care should be taken when reading or modifying raw, adaptive bytecode containing quickened data.

3.11 新版功能.

一元操作

一元操作获取堆栈顶部元素,应用操作,并将结果推回堆栈。

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

Binary and in-place operations

二元操作从堆栈中删除堆栈顶部(TOS)和第二个最顶层堆栈项(TOS1)。 它们执行操作,并将结果放回堆栈。

就地操作就像二元操作,因为它们删除了TOS和TOS1,并将结果推回到堆栈上,但是当TOS1支持它时,操作就地完成,并且产生的TOS可能是(但不一定) 原来的TOS1。

BINARY_OP(op)

Implements the binary and in-place operators (depending on the value of op).

3.11 新版功能.

BINARY_SUBSCR

实现 TOS = TOS1[TOS]

STORE_SUBSCR

实现 TOS1[TOS] = TOS2

DELETE_SUBSCR

实现 del TOS1[TOS]

协程操作码

GET_AWAITABLE(where)

实现 TOS = get_awaitable(TOS) ,其中 get_awaitable(o) 返回 o 如果 o 是一个有 CO_ITERABLE_COROUTINE 标志的协程对象或生成器对象,否则解析 o.__await__

If the where operand is nonzero, it indicates where the instruction occurs:

  • 1 After a call to __aenter__

  • 2 After a call to __aexit__

3.5 新版功能.

在 3.11 版更改: Previously, this instruction did not have an oparg.

GET_AITER

实现 TOS = TOS.__aiter__()

3.5 新版功能.

在 3.7 版更改: 已经不再支持从 __aiter__ 返回可等待对象。

GET_ANEXT

Pushes get_awaitable(TOS.__anext__()) to the stack. See GET_AWAITABLE for details about get_awaitable.

3.5 新版功能.

END_ASYNC_FOR

Terminates an async for loop. Handles an exception raised when awaiting a next item. If TOS is StopAsyncIteration pop 3 values from the stack and restore the exception state using the second of them. Otherwise re-raise the exception using the value from the stack. An exception handler block is removed from the block stack.

3.8 新版功能:

在 3.11 版更改: Exception representation on the stack now consist of one, not three, items.

BEFORE_ASYNC_WITH

从栈顶对象解析 __aenter____aexit__ 。将 __aexit____aenter__() 的结果推入堆栈。

3.5 新版功能.

其他操作码

PRINT_EXPR

实现交互模式的表达式语句。TOS从堆栈中被移除并打印。在非交互模式下,表达式语句以 POP_TOP 终止。

SET_ADD(i)

调用 set.add(TOS1[-i], TOS) 。 用于实现集合推导。

LIST_APPEND(i)

调用 list.append(TOS1[-i], TOS)。 用于实现列表推导式。

MAP_ADD(i)

调用 dict.__setitem__(TOS1[-i], TOS1, TOS) 。 用于实现字典推导。

3.1 新版功能.

在 3.8 版更改: 映射值为 TOS ,映射键为 TOS1 。之前,它们被颠倒了。

对于所有 SET_ADDLIST_APPENDMAP_ADD 指令,当弹出添加的值或键值对时,容器对象保留在堆栈上,以便它可用于循环的进一步迭代。

RETURN_VALUE

返回 TOS 到函数的调用者。

YIELD_VALUE

弹出 TOS 并从一个 generator 生成它。

SETUP_ANNOTATIONS

检查 __annotations__ 是否在 locals() 中定义,如果没有,它被设置为空 dict 。只有在类或模块体静态地包含 variable annotations 时才会发出此操作码。

3.6 新版功能.

IMPORT_STAR

将所有不以 '_' 开头的符号直接从模块 TOS 加载到局部命名空间。加载所有名称后弹出该模块。这个操作码实现了 from module import *

POP_EXCEPT

Pops a value from the stack, which is used to restore the exception state.

在 3.11 版更改: Exception representation on the stack now consist of one, not three, items.

RERAISE

Re-raises the exception currently on top of the stack. If oparg is non-zero, pops an additional value from the stack which is used to set f_lasti of the current frame.

3.9 新版功能.

在 3.11 版更改: Exception representation on the stack now consist of one, not three, items.

PUSH_EXC_INFO

Pops a value from the stack. Pushes the current exception to the top of the stack. Pushes the value originally popped back to the stack. Used in exception handlers.

3.11 新版功能.

CHECK_EXC_MATCH

Performs exception matching for except. Tests whether the TOS1 is an exception matching TOS. Pops TOS and pushes the boolean result of the test.

3.11 新版功能.

CHECK_EG_MATCH

Performs exception matching for except*. Applies split(TOS) on the exception group representing TOS1.

In case of a match, pops two items from the stack and pushes the non-matching subgroup (None in case of full match) followed by the matching subgroup. When there is no match, pops one item (the match type) and pushes None.

3.11 新版功能.

PREP_RERAISE_STAR

Combines the raised and reraised exceptions list from TOS, into an exception group to propagate from a try-except* block. Uses the original exception group from TOS1 to reconstruct the structure of reraised exceptions. Pops two items from the stack and pushes the exception to reraise or None if there isn't one.

3.11 新版功能.

WITH_EXCEPT_START

Calls the function in position 4 on the stack with arguments (type, val, tb) representing the exception at the top of the stack. Used to implement the call context_manager.__exit__(*exc_info()) when an exception has occurred in a with statement.

3.9 新版功能.

在 3.11 版更改: The __exit__ function is in position 4 of the stack rather than 7. Exception representation on the stack now consist of one, not three, items.

LOAD_ASSERTION_ERROR

AssertionError 推入栈顶。 由 assert 语句使用。

3.9 新版功能.

LOAD_BUILD_CLASS

Pushes builtins.__build_class__() onto the stack. It is later called to construct a class.

BEFORE_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_EXCEPT_START. Then, __enter__() is called. Finally, the result of calling the __enter__() method is pushed onto the stack.

3.11 新版功能.

GET_LEN

len(TOS) 推入栈顶。

3.10 新版功能.

MATCH_MAPPING

如果 TOS 是 collections.abc.Mapping 的实例(或者更准确地说:如果在它的 tp_flags 中设置了 Py_TPFLAGS_MAPPING 旗标),则将 True 推入栈顶。 否则,推入 False

3.10 新版功能.

MATCH_SEQUENCE

如果 TOS 是 collections.abc.Sequence 的实例而 不是 str/bytes/bytearray 的实例(或者更准确地说:如果在它的 tp_flags 中设置了 Py_TPFLAGS_SEQUENCE 旗标),则将 True 推入栈顶。 否则 ,推入 False

3.10 新版功能.

MATCH_KEYS

TOS is a tuple of mapping keys, and TOS1 is the match subject. If TOS1 contains all of the keys in TOS, push a tuple containing the corresponding values. Otherwise, push None.

3.10 新版功能.

在 3.11 版更改: Previously, this instruction also pushed a boolean value indicating success (True) or failure (False).

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

LIST_TO_TUPLE

从堆栈中弹出一个列表并推入一个包含相同值的元组。

3.9 新版功能.

LIST_EXTEND(i)

调用 list.extend(TOS1[-i], TOS)。 用于构建列表。

3.9 新版功能.

SET_UPDATE(i)

调用 set.update(TOS1[-i], TOS)。 用于构建集合。

3.9 新版功能.

DICT_UPDATE(i)

调用 dict.update(TOS1[-i], TOS)。 用于构建字典。

3.9 新版功能.

DICT_MERGE(i)

类似于 DICT_UPDATE 但对于重复的键会引发异常。

3.9 新版功能.

LOAD_ATTR(namei)

将 TOS 替换为 getattr(TOS, co_names[namei])

COMPARE_OP(opname)

执行布尔运算操作。 操作名称可在 cmp_op[opname] 中找到。

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]。 会弹出 TOS 和 TOS1 以提供 fromlistlevel 参数给 __import__()。 模块对象会被推入栈顶。 当前命名空间不受影响:对于一条标准 import 语句,会执行后续的 STORE_FAST 指令来修改命名空间。

IMPORT_FROM(namei)

从在 TOS 内找到的模块中加载属性 co_names[namei]。 结果对象会被推入栈顶,以便由后续的 STORE_FAST 指令来保存。

JUMP_FORWARD(delta)

将字节码计数器的值增加 delta

JUMP_BACKWARD(delta)

Decrements bytecode counter by delta. Checks for interrupts.

3.11 新版功能.

JUMP_BACKWARD_NO_INTERRUPT(delta)

Decrements bytecode counter by delta. Does not check for interrupts.

3.11 新版功能.

POP_JUMP_FORWARD_IF_TRUE(delta)

If TOS is true, increments the bytecode counter by delta. TOS is popped.

3.11 新版功能.

POP_JUMP_BACKWARD_IF_TRUE(delta)

If TOS is true, decrements the bytecode counter by delta. TOS is popped.

3.11 新版功能.

POP_JUMP_FORWARD_IF_FALSE(delta)

If TOS is false, increments the bytecode counter by delta. TOS is popped.

3.11 新版功能.

POP_JUMP_BACKWARD_IF_FALSE(delta)

If TOS is false, decrements the bytecode counter by delta. TOS is popped.

3.11 新版功能.

POP_JUMP_FORWARD_IF_NOT_NONE(delta)

If TOS is not None, increments the bytecode counter by delta. TOS is popped.

3.11 新版功能.

POP_JUMP_BACKWARD_IF_NOT_NONE(delta)

If TOS is not None, decrements the bytecode counter by delta. TOS is popped.

3.11 新版功能.

POP_JUMP_FORWARD_IF_NONE(delta)

If TOS is None, increments the bytecode counter by delta. TOS is popped.

3.11 新版功能.

POP_JUMP_BACKWARD_IF_NONE(delta)

If TOS is None, decrements the bytecode counter by delta. TOS is popped.

3.11 新版功能.

JUMP_IF_TRUE_OR_POP(delta)

If TOS is true, increments the bytecode counter by delta and leaves TOS on the stack. Otherwise (TOS is false), TOS is popped.

3.1 新版功能.

在 3.11 版更改: The oparg is now a relative delta rather than an absolute target.

JUMP_IF_FALSE_OR_POP(delta)

If TOS is false, increments the bytecode counter by delta and leaves TOS on the stack. Otherwise (TOS is true), TOS is popped.

3.1 新版功能.

在 3.11 版更改: The oparg is now a relative delta rather than an absolute target.

FOR_ITER(delta)

TOS 是一个 iterator。 请调用其 __next__() 方法。 如果此操作产生了一个新值,则将其推入栈顶(将迭代器留在其下方)。 如果迭代器提示已耗尽,TOS 会被弹出,并且字节码计数器将增加 delta

LOAD_GLOBAL(namei)

Loads the global named co_names[namei>>1] onto the stack.

在 3.11 版更改: If the low bit of namei is set, then a NULL is pushed to the stack before the global variable.

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]

MAKE_CELL(i)

Creates a new cell in slot i. If that slot is empty then that value is stored into the new cell.

3.11 新版功能.

LOAD_CLOSURE(i)

Pushes a reference to the cell contained in slot i of the "fast locals" storage. The name of the variable is co_fastlocalnames[i].

Note that LOAD_CLOSURE is effectively an alias for LOAD_FAST. It exists to keep bytecode a little more readable.

在 3.11 版更改: i is no longer offset by the length of co_varnames.

LOAD_DEREF(i)

Loads the cell contained in slot i of the "fast locals" storage. Pushes a reference to the object the cell contains on the stack.

在 3.11 版更改: i is no longer offset by the length of co_varnames.

LOAD_CLASSDEREF(i)

类似于 LOAD_DEREF 但在查询单元之前会首先检查局部对象字典。 这被用于加载类语句体中的自由变量。

3.4 新版功能.

在 3.11 版更改: i is no longer offset by the length of co_varnames.

STORE_DEREF(i)

Stores TOS into the cell contained in slot i of the "fast locals" storage.

在 3.11 版更改: i is no longer offset by the length of co_varnames.

DELETE_DEREF(i)

Empties the cell contained in slot i of the "fast locals" storage. Used by the del statement.

3.2 新版功能.

在 3.11 版更改: i is no longer offset by the length of co_varnames.

COPY_FREE_VARS(n)

Copies the n free variables from the closure into the frame. Removes the need for special code on the caller's side when calling closures.

3.11 新版功能.

RAISE_VARARGS(argc)

使用 raise 语句的 3 种形式之一引发异常,具体形式取决于 argc 的值:

  • 0: raise (重新引发之前的异常)

  • 1: raise TOS (在 TOS 上引发异常实例或类型)

  • 2: raise TOS1 from TOS (在 TOS1 上引发异常实例或类型并将 __cause__ 设为 TOS)

CALL(argc)

Calls a callable object with the number of arguments specified by argc, including the named arguments specified by the preceding KW_NAMES, if any. On the stack are (in ascending order), either:

  • NULL

  • The callable

  • The positional arguments

  • The named arguments

or:

  • The callable

  • self

  • The remaining positional arguments

  • The named arguments

argc is the total of the positional and named arguments, excluding self when a NULL is not present.

CALL pops all arguments and the callable object off the stack, calls the callable object with those arguments, and pushes the return value returned by the callable object.

3.11 新版功能.

CALL_FUNCTION_EX(flags)

调用一个可调用对象并附带位置参数和关键字参数变量集合。 如果设置了 flags 的最低位,则栈顶包含一个由额外关键字参数组成的映射对象。 在调用该可调用对象之前,映射对象和可迭代对象会被分别“解包”并将它们的内容分别作为关键字参数和位置参数传入。 CALL_FUNCTION_EX 会中栈中弹出所有参数及可调用对象,附带这些参数调用该可调用对象,并将可调用对象所返回的返回值推入栈顶。

3.6 新版功能.

LOAD_METHOD(namei)

Loads a method named co_names[namei] from the TOS object. TOS is popped. This bytecode distinguishes two cases: if TOS has a method with the correct name, the bytecode pushes the unbound method and TOS. TOS will be used as the first argument (self) by CALL when calling the unbound method. Otherwise, NULL and the object return by the attribute lookup are pushed.

3.7 新版功能.

PRECALL(argc)

Prefixes CALL. Logically this is a no op. It exists to enable effective specialization of calls. argc is the number of arguments as described in CALL.

3.11 新版功能.

PUSH_NULL

Pushes a NULL to the stack. Used in the call sequence to match the NULL pushed by LOAD_METHOD for non-method calls.

3.11 新版功能.

KW_NAMES(i)

Prefixes PRECALL. Stores a reference to co_consts[consti] into an internal variable for use by CALL. co_consts[consti] must be a tuple of strings.

3.11 新版功能.

MAKE_FUNCTION(flags)

将一个新函数对象推入栈顶。 从底端到顶端,如果参数带有指定的旗标值则所使用的栈必须由这些值组成。

  • 0x01 一个默认值的元组,用于按位置排序的仅限位置形参以及位置或关键字形参

  • 0x02 一个仅限关键字形参的默认值的字典

  • 0x04 一个包含形参标注的字符串元组。

  • 0x08 一个包含用于自由变量的单元的元组,生成一个闭包

  • 与函数相关联的代码 (在 TOS1)

  • 函数的 qualified name (在 TOS)

在 3.10 版更改: 旗标值 0x04 是一个字符串元组而非字典。

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

MATCH_CLASS(count)

TOS 是一个包含关键字属性名称的元组,TOS1 是要匹配的类,而 TOS2 是匹配目标。 count 是位置子模式的数量。

Pop TOS, TOS1, and TOS2. If TOS2 is an instance of TOS1 and has the positional and keyword attributes required by count and TOS, push a tuple of extracted attributes. Otherwise, push None.

3.10 新版功能.

在 3.11 版更改: Previously, this instruction also pushed a boolean value indicating success (True) or failure (False).

RESUME(where)

A no-op. Performs internal tracing, debugging and optimization checks.

The where operand marks where the RESUME occurs:

  • 0 The start of a function

  • 1 After a yield expression

  • 2 After a yield from expression

  • 3 After an await expression

3.11 新版功能.

RETURN_GENERATOR

Create a generator, coroutine, or async generator from the current frame. Clear the current frame and return the newly created generator.

3.11 新版功能.

SEND

Sends None to the sub-generator of this generator. Used in yield from and await statements.

3.11 新版功能.

ASYNC_GEN_WRAP

Wraps the value on top of the stack in an async_generator_wrapped_value. Used to yield in async generators.

3.11 新版功能.

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

布尔运算的字节码序列。