"dis" --- Python bytecode的反組譯器
***********************************

**原始碼：**Lib/dis.py

======================================================================

"dis" 模組支援反組譯分析 CPython *bytecode*。CPython bytecode 作為輸入
的模組被定義於 "Include/opcode.h" 並且被編譯器和直譯器所使用。

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

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

在 3.10 版的變更: 跳转、异常处理和循环指令的参数现在将为指令偏移量而不
是字节偏移量。

在 3.11 版的變更: 有些指令带有一个或多个内联缓存条目，它们是采用
"CACHE" 指令的形式。 这些指令默认是隐藏的，但可以通过将
"show_caches=True" 传给任何 "dis" 工具对象来显示。 此外，解释器现在会
适配字节码以使其能针对不同的运行时条件实现专门化。 适配的字节码可通过
传入 "adaptive=True" 来显示。

示例：给出函数 "myfunc()":

   def myfunc(alist):
       return len(alist)

以下命令可被用来显示 "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" 是行号)。


命令行接口
==========

"dis" 模块可以在命令行下作为一个脚本来唤起：

   python -m dis [-h] [-C] [infile]

可以接受以下选项：

-h, --help

   显示用法并退出。

-C, --show-caches

   显示内联缓存。

如果指定了 "infile"，其反汇编代码将被写入到标准输出。 否则，反汇编将在
从标准输入接收的已编译源代码上进行。


字节码分析
==========

在 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()" 将针对指定的操作码显示“当前指令”标记。

   如果 *show_caches* 为 "True"，"dis()" 将显示解释器用来专门化字节码
   的内联缓存条目。

   如果 *adaptive* 为 "True"，"dis()" 将显示可能不同于原始字节码的专门
   化字节码。

   classmethod from_traceback(tb, *, show_caches=False)

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

   codeobj

      已编译的代码对象。

   first_line

      代码对象的第一个源代码行（如果可用）

   dis()

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

   info()

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

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

   在 3.11 版的變更: 新增 *show_caches* 與 *adaptive* 參數。

範例：

   >>> 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* 限制，除非它是 "None" 。 "depth=0" 表示没
   有递归。

   如果 *show_caches* 为 "True"，此函数将显示解释器用来专门化字节码的
   内联缓存条目。

   如果 *adaptive* 为 "True"，此函数将显示可能不同于原始字节码的专门化
   字节码。

   在 3.4 版的變更: 新增 *file* 參數。

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

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

   在 3.11 版的變更: 新增 *show_caches* 與 *adaptive* 參數。

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

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

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

   在 3.4 版的變更: 新增 *file* 參數。

   在 3.11 版的變更: 新增 *show_caches* 與 *adaptive* 參數。

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 版的變更: 新增 *show_caches* 與 *adaptive* 參數。

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

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

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

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

   *show_caches* 和 *adaptive* 形参的作用与 "dis()" 中的同名形参相同。

   在 3.4 版新加入.

   在 3.11 版的變更: 新增 *show_caches* 與 *adaptive* 參數。

dis.findlinestarts(code)

   这个生成器函数使用 代码对象 *code* 的 "co_lines()" 方法来查找源代码
   中行开头的偏移量。 它们将作为 "(offset, lineno)" 对被生成。

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

   在 3.10 版的變更: 使用 **PEP 626** "co_lines()" 方法而不是 代码对象
   的 "co_firstlineno" 和 "co_lnotab" 属性。

dis.findlabels(code)

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

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

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

   如果代码有一个跳转目标并且 *jump* 是 "True" ，则 "drag_effect()" 将
   返回跳转的堆栈效果。如果 *jump* 是 "False" ，它将返回不跳跃的堆栈效
   果。如果 *jump* 是 "None" （默认值），它将返回两种情况的最大堆栈效
   果。

   在 3.4 版新加入.

   在 3.8 版的變更: 新增 *jump* 參數。


Python字节码说明
================

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

class dis.Instruction

   字节码操作的详细信息

   opcode

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

   opname

      人类可读的操作名称

   arg

      操作的数字参数（如果有的话），否则为 "None"

   argval

      已解析的 arg 值（如果有的话），否则为 "None"

   argrepr

      人类可读的操作参数（如果存在）的描述，否则为空字符串。

   offset

      在字节码序列中的起始操作索引

   starts_line

      行由此操作码（如果有）启动，否则为 "None"

   is_jump_target

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

   positions

      "dis.Positions" 对象保存了这条指令所涵盖的起始和结束位置。

   在 3.4 版新加入.

   在 3.11 版的變更: 增加了 "positions" 字段。

class dis.Positions

   考虑到此信息不可用的情况，某些字段可能为 "None"。

   lineno

   end_lineno

   col_offset

   end_col_offset

   在 3.11 版新加入.

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

**一般指令**

NOP

   无操作代码。 被字节码优化器用作占位符，以及生成行追踪事件。

POP_TOP

   删除堆栈顶部（TOS）项。

COPY(i)

   将第 *i* 项推入栈顶。 该项不会从其原始位置移除。

   在 3.11 版新加入.

SWAP(i)

   将 TOS 与位置 *i* 处的项交换。

   在 3.11 版新加入.

CACHE

   此操作码不是真正的指令，它被用来为解释器标记额外空间以便在字节码中
   直接缓存有用的数据。 它会被所有 "dis" 工具自动隐藏，但可以通过
   "show_caches=True" 来查看。

   从逻辑上说，此空间是之前的指令的组成部分。 许多操作码都预期带有固定
   数量的缓存，并会指示解释器在运行时跳过它们。

   被填充的缓存看起来可以像是任意的指令，因此在读取或修改包含快取数据
   的原始自适应字节码时应当非常小心。

   在 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 iterator* 或 *coroutine* 对象则保持原
   样。否则实现 "TOS = iter(TOS)" 。

   在 3.5 版新加入.

**双目和原地操作**

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

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

BINARY_OP(op)

   实现二元和就地运算符（取决于 *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__" 。

      如果 "where" 操作数为非零值，则表示指令所在的位置:

      * "1" 在调用 "__aenter__" 之后

      * "2" 在调用 "__aexit__" 之后

   在 3.5 版新加入.

   在 3.11 版的變更: 在之前版本中，该指令没有 oparg。

GET_AITER

   实现 "TOS = TOS.__aiter__()" 。

   在 3.5 版新加入.

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

GET_ANEXT

   将 "get_awaitable(TOS.__anext__())" 推入栈。 请参阅 "GET_AWAITABLE"
   了解有关 "get_awaitable" 的详情。

   在 3.5 版新加入.

END_ASYNC_FOR

   终止 "async for" 循环。 处理在等待下一项时引发的异常。 栈中在 TOS1
   处包含异步可迭代对象，在 TOS 处包含所引发的异常。 两者都会被弹出。
   如果该异常不是 "StopAsyncIteration"，则会重新引发它。

   在 3.8 版新加入.

   在 3.11 版的變更: 栈中的异常表示形式现在将由一个而不是三个条目组成
   。

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_ADD" 、 "LIST_APPEND" 和 "MAP_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

   从栈中弹出一个值，它将被用来恢复异常状态。

   在 3.11 版的變更: 栈中的异常表示形式现在将由一个而不是三个条目组成
   。

RERAISE

   重新引发当前位于栈顶的异常。 如果 oparg 为非零值，则从栈顶额外弹出
   一个值用来设置当前帧的 "f_lasti"。

   在 3.9 版新加入.

   在 3.11 版的變更: 栈中的异常表示形式现在将由一个而不是三个条目组成
   。

PUSH_EXC_INFO

   从栈中弹出一个值。 将当前异常推入栈顶。 将原先被弹出的值推回栈。 在
   异常处理器中使用。

   在 3.11 版新加入.

CHECK_EXC_MATCH

   为 "except" 执行异常匹配。 测试 TOS1 是否为匹配 TOS 的异常。 弹出
   TOS 并推入测试的布尔结果。

   在 3.11 版新加入.

CHECK_EG_MATCH

   为 "except*" 执行异常匹配。 对代表 TOS1 的异常组应用 "split(TOS)"。

   在匹配的情况下，从栈中弹出两项并推入不匹配的子分组 (如完全匹配则为
   "None") 以及匹配的子分组。 当没有任何匹配时，则弹出一项 (匹配类型)
   并推入 "None"。

   在 3.11 版新加入.

PREP_RERAISE_STAR

   将来自 TOS 的引发和重新引发的异常列表合并为一个异常组，以便从 try-
   except* 块向外传播。 使用来自 TOS1 的原始异常组来重构重新引发的异常
   的结构。 从栈中弹出两项，并推入要重新引发的异常（如果没有则推入
   "None"）。

   在 3.11 版新加入.

WITH_EXCEPT_START

   调用栈中 4 号位置上的函数并附带代表位于栈顶的异常的参数 (type, val,
   tb)。 用于在 "with" 语句内发生异常时实现调用
   "context_manager.__exit__(*exc_info())"。

   在 3.9 版新加入.

   在 3.11 版的變更: "__exit__" 函数位于栈的 4 号位而不是 7 号位。 栈
   中的异常表示形式现在由一项而不是三项组成。

LOAD_ASSERTION_ERROR

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

   在 3.9 版新加入.

LOAD_BUILD_CLASS

   将 "builtins.__build_class__()" 推入栈。 之后它将会被调用来构造一个
   类。

BEFORE_WITH(delta)

   此操作码会在 with 代码块开始之前执行多个操作。 首先，它将从上下文管
   理器加载 "__exit__()" 并将其推入栈顶以供 "WITH_EXCEPT_START" 后续使
   用。 然后，将调用 "__enter__()"。 最后，将调用 "__enter__()" 方法的
   结果推入栈顶。

   在 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 是一个映射键组成的元组，而 TOS1 是匹配目标。 如果 TOS1 包含 TOS
   中的所有键，则推入一个包含相应值的 "tuple"。 否则推入 "None"。

   在 3.10 版新加入.

   在 3.11 版的變更: 在之前的版本中，该指令还会推入一个表示成功
   ("True") 或失败 ("False") 的布尔值。

STORE_NAME(namei)

   实现 "name = TOS"。 *namei* 是 *name* 在 代码对象 的 "co_names" 属
   性中的索引。 编译器会尽可能尝试使用 "STORE_FAST" 或 "STORE_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 以提供 *fromlist*
   和 *level* 参数给 "__import__()"。 模块对象会被推入栈顶。 当前命名
   空间不受影响：对于一条标准 import 语句，会执行后续的 "STORE_FAST"
   指令来修改命名空间。

IMPORT_FROM(namei)

   从在 TOS 内找到的模块中加载属性 "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_FORWARD_IF_TRUE(delta)

   如果 TOS 为真值，则将字节码计数器的值增加 *delta*。 TOS 会被弹出。

   在 3.11 版新加入.

POP_JUMP_BACKWARD_IF_TRUE(delta)

   如果 TOS 为真值，则将字节码计数器的值减少 *delta*。 TOS 会被弹出。

   在 3.11 版新加入.

POP_JUMP_FORWARD_IF_FALSE(delta)

   如果 TOS 为假值，则将字节码计数器的值增加 *delta*。 TOS 会被弹出。

   在 3.11 版新加入.

POP_JUMP_BACKWARD_IF_FALSE(delta)

   如果 TOS 为假值，则将字节码计数器的值减少 *delta*。 TOS 会被弹出。

   在 3.11 版新加入.

POP_JUMP_FORWARD_IF_NOT_NONE(delta)

   如果 TOS 不为 "None"，则将字节码计数器的值增加 *delta*。 TOS 会被弹
   出。

   在 3.11 版新加入.

POP_JUMP_BACKWARD_IF_NOT_NONE(delta)

   如果 TOS 不为 "None"，则将字节码计数器的值减少 *delta*。 TOS 会被弹
   出。

   在 3.11 版新加入.

POP_JUMP_FORWARD_IF_NONE(delta)

   如果 TOS 为 "None"，则将字节码计数器的值增加 *delta*。 TOS 会被弹出
   。

   在 3.11 版新加入.

POP_JUMP_BACKWARD_IF_NONE(delta)

   如果 TOS 为 "None"，则将字节码计数器的值减少 *delta*。 TOS 会被弹出
   。

   在 3.11 版新加入.

JUMP_IF_TRUE_OR_POP(delta)

   如果 TOS 为真值，则将字节码计数器的值增加 *delta* 并将 TOS 保留在栈
   上。 否则（TOS 为假值），TOS 会被弹出。

   在 3.1 版新加入.

   在 3.11 版的變更: oparg 现在是一个相对增量而不是绝对目标。

JUMP_IF_FALSE_OR_POP(delta)

   如果 TOS 为假值，则将字节码计数器的值增加 *delta* 并将 TOS 保留在栈
   上。 否则（TOS 为真值），TOS 会被弹出。

   在 3.1 版新加入.

   在 3.11 版的變更: oparg 现在是一个相对增量而不是绝对目标。

FOR_ITER(delta)

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

LOAD_GLOBAL(namei)

   将名为 "co_names[namei>>1]" 的全局对象加载到栈顶。

   在 3.11 版的變更: 如果设置了 "namei" 的低比特位，则会在全局变量前将
   一个 "NULL" 推入栈。

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)

   在槽位 "i" 中创建一个新单元。 如果该槽位为非空则该值将存储到新单元
   中。

   在 3.11 版新加入.

LOAD_CLOSURE(i)

   推入一个指向包含在 "fast locals" 存储的 "i" 号槽位的单元的引用。 变
   量名为 "co_fastlocalnames[i]"。

   注意 "LOAD_CLOSURE" 实际上是 "LOAD_FAST" 的一个别名。 它的存在是为
   了让字节码的可读性更好一些。

   在 3.11 版的變更: "i" 不再是长度为 "co_varnames" 的偏移量。

LOAD_DEREF(i)

   加载包含在 "fast locals" 存储的 "i" 号槽位中的单元。 将一个指向该单
   元所包含对象的引用推入栈。

   在 3.11 版的變更: "i" 不再是 "co_varnames" 的长度的偏移量。

LOAD_CLASSDEREF(i)

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

   在 3.4 版新加入.

   在 3.11 版的變更: "i" 不再是长度为 "co_varnames" 的偏移量。

STORE_DEREF(i)

   将 TOS 存放到包含在 "fast locals" 存储的 "i" 号槽位中的单元内。

   在 3.11 版的變更: "i" 不再是 "co_varnames" 的长度的偏移量。

DELETE_DEREF(i)

   清空 "fast locals" 存储中包含在 "i" 号槽位的单元。 被用于 "del" 语
   句。

   在 3.2 版新加入.

   在 3.11 版的變更: "i" 不再是 "co_varnames" 的长度的偏移量。

COPY_FREE_VARS(n)

   将 "n" 个自由变量从闭包拷贝到帧中。 当调用闭包时不再需要调用方添加
   特殊的代码。

   在 3.11 版新加入.

RAISE_VARARGS(argc)

   使用 "raise" 语句的 3 种形式之一引发异常，具体形式取决于 *argc* 的
   值：

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

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

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

CALL(argc)

   调用一个可调用对象并传入由 "argc" 所指定数量的参数，包括之前的
   "KW_NAMES" 所指定的关键字参数，如果有的话。 在栈上（按升序排列），
   可以是:

   * NULL

   * 可调用对象

   * 位置参数

   * 关键字参数

   或者:

   * 可调用对象

   * "self"

   * 其余的位置参数

   * 关键字参数

   "argc" 是位置和关键字参数的总和，当未提供 "NULL" 时将排除 "self"。

   "CALL" 将把所有参数和可调用对象弹出栈，附带这些参数调用该可调用对象
   ，并将该可调用对象的返回值推入栈。

   在 3.11 版新加入.

CALL_FUNCTION_EX(flags)

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

   在 3.6 版新加入.

LOAD_METHOD(namei)

   从 TOS 对象加载名为 "co_names[namei]" 的方法。 TOS 会被弹出。 此字
   节码区分两种情况：如果 TOS 具有正确名称的方法，该字节码会推入未绑定
   方法和 TOS。 在调用未绑定方法时，TOS 将被 "CALL" 用作第一个参数
   ("self")。 否则，将推入 "NULL" 以及由属性查找所返回的对象。

   在 3.7 版新加入.

PRECALL(argc)

   作为 "CALL" 的前缀。 逻辑上这是一个空操作。 它的存在是为了实现调用
   的有效特化。 "argc" 是如 "CALL" 中所述的参数数量。

   在 3.11 版新加入.

PUSH_NULL

      将一个 "NULL" 推入栈。 在调用序列中用来匹配 "LOAD_METHOD" 针对非
      方法调用推入栈的 "NULL"。

   在 3.11 版新加入.

KW_NAMES(i)

   作为 "PRECALL" 的前缀。 将指向 "co_consts[consti]" 的引用存储到内部
   变量中以供 "CALL" 使用。 "co_consts[consti]" 必须是一个字符串元组。

   在 3.11 版新加入.

MAKE_FUNCTION(flags)

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

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

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

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

   * "0x08" 一个包含用于自由变量的单元的元组，生成一个闭包

   * 与函数关联的代码（位于 TOS）

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

   在 3.11 版的變更: 移除了位于 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*，然后是一个必须的 *value*。 *flags* 的解读方式如下：

   * "(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* 是位置子模式的数量。

   弹出 TOS、 TOS1 和 TOS2。 如果 TOS2 是 TOS1 的实例，并且具有
   *count* 和 TOS 所要求的位置和关键字属性，则推入一个由提取出的属性组
   成的元组。 否则推入 "None"。

   在 3.10 版新加入.

   在 3.11 版的變更: 在之前的版本中，该指令还会推入一个表示成功
   ("True") 或失败 ("False") 的布尔值。

RESUME(where)

      空操作。 执行内部追踪、调试和优化检查。

      "where" 操作数标记 "RESUME" 在哪里发生:

      * "0" 函数的开头

      * "1" 在 "yield" 表达式之后

      * "2" 在 "yield from" 表达式之后

      * "3" 在 "await" 表达式之后

   在 3.11 版新加入.

RETURN_GENERATOR

   从当前帧创建一个生成器、协程或异步生成器。 清空当前帧并返回新创建的
   生成器。

   在 3.11 版新加入.

SEND

   向此生成器的子生成器发送 "None"。 用于 "yield from" 和 "await" 语句
   。

   在 3.11 版新加入.

ASYNC_GEN_WRAP

   将栈顶的值包装在一个 "async_generator_wrapped_value" 中。 用于在异
   步生成器中进行 yield。

   在 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

   布尔运算的字节码序列。
