dis– Python字节码的反汇编程序

源代码: Lib / dis.py


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

CPython实现细节:字节码是一个实现细节CPython翻译。使用Noguarantees不会在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 instances.

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

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

classmethod from_traceback (tb)
从给定的回溯构造一个Bytecode实例,将current_offset设置为负责异常的指令.
codeobj
编译后的代码对象.
first_line
代码对象的第一个源代码行(如果有的话)
dis
返回字节码的格式化视图操作(与dis.dis()打印相同,但以多行字符串形式返回).
info
返回格式化的多行包含有关code对象的详细信息的字符串,如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_infox
返回带格式的多行字符串提供的函数,生成器,异步生成器,协同程序,方法,源代码字符串或代码对象的详细代码对象信息.

请注意,代码信息字符串的确切内容是高度依赖于实现的,它们可能会在Python VM或Pythonreleases中随意更改

新版本3.2.

更改版本3.7:这现在可以处理协同程序和异步生成器对象.

dis.show_code(x, *, file=None)
打印提供的函数,方法,源代码字符串或代码对象的详细代码对象信息。file(或sys.stdout如果没有指定file).

这是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的限制,除非它是None.depth=0表示没有递归.

在版本3.4中更改:添加了file参数

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

更改版本3.7:现在可以处理协同程序和异步生成器对象了.

dis.distbtb=None, *, file=None)
如果没有传递,则使用lasttraceback来组装回溯的堆栈函数。指示导致异常的指令.

如果提供的话,反汇编被写成所提供的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 parameter.

dis.get_instructions(x, *, first_line=None)
在所提供的函数,方法,源代码字符串或代码对象中的指令上返回一个迭代器.

迭代器生成一系列Instruction命名元组在提供的代码中给出每个操作的详细信息.

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

版本3.4.

dis.findlinestarts(code)
这个生成器函数使用co_firstlinenoco_lnotab代码对象的属性code找到源代码中起始线的偏移量。它们生成为(offset, lineno)对。查看对象/ lnotab_notes.txt为co_lnotab格式并以如何解码它.

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

dis.findlabels (code
检测代码对象中的所有偏移量code这是跳跃目标,并返回这些偏移的列表.
dis.stack_effect (opcode [, oparg])
计算叠加效果opcode带有参数oparg.

版本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生成器迭代器 coroutine objectit保持原样。否则,实施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__返回等待的对象是没有longersupported.

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
由于break声明而终止一个循环
CONTINUE_LOOP (target)
由于continue语句而继续循环。target是跳到的地址(应该是FOR_ITER指令).
SET_ADDi
打电话set.add(TOS1[-i], TOS)。用于实现集合理解.
LIST_APPENDi
打电话list.append(TOS[-i], TOS)。用于实现列表理解.
MAP_ADDi
打电话dict.setitem(TOS1[-i], TOS, TOS1)。用于实现dictcomprehensions.

版本3.1.

中的全新内容//适用于SET_ADD, LIST_APPENDMAP_ADD指令,当弹出附加值或键/值对时,容器对象保留在堆栈中,以便它可用于循环的进一步操作.

RETURN_VALUE
用TOS返回函数的调用者.
YIELD_VALUE
弹出TOS并从产生它发电机.
YIELD_FROM
Pops TOS并作为@的副主席委托给它发电机.

3.3版本中的新功能

SETUP_ANNOTATIONS
检查__annotations__是否在locals()中定义,如果没有,则设置为空dict。只有当classor模块体包含变量注释静态时才会发出此操作码.

版本3.6.

IMPORT_STAR
加载所有不以"_"直接从模块TOS到本地命名空间。加载所有名称后弹出该模块。Thisopcode实现from module import *.
POP_BLOCK
从块堆栈中删除一个块。每帧,有一堆块,表示嵌套循环,try语句等等.
POP_EXCEPT
从块堆栈中删除一个块。弹出的块必须是异常处理程序块,在进入except处理程序时隐式创建。除了从帧堆栈中弹出无关的值之外,最后三个popped值用于恢复异常状态.
END_FINALLY
终止finally子句。解释器回忆起是否必须重新提出异常,或者函数是否返回,并继续使用外部下一个块
LOAD_BUILD_CLASS
builtins.__build_class__()到堆栈上。它后来被称为CALL_FUNCTION建一个课.
SETUP_WITHdelta
此操作码在with块启动之前执行多个操作。首先,它加载__exit__()从上下文管理器中将它推到堆栈上以便以后使用WITH_CLEANUP。然后,调用__enter__(),最后一个块指向delta被推了。最后,调用enter方法的结果被推到堆栈上。下一个操作码要么忽略它(POP_TOP),要把它放在(a)变量中(STORE_FAST, STORE_NAME,或UNPACK_SEQUENCE)。

版本3.2.

WITH_CLEANUP_START
中的新功能当with语句块退出时清除堆栈。TOS是上下文管理员__exit__()约束方法。在TOS下面有1-3个值表示如何/为什么输入finally子句:

  • SECOND = None
  • (SECOND,THIRD)=(WHY_{RETURN,CONTINUE}),retval
  • SECOND = WHY_*;它下面没有倒退
  • (第二,第三,第四)= exc_info()

在最后一种情况下,调用TOS(SECOND, THIRD, FOURTH),否则调用TOS(None, None, None)。推送SECOND和调用栈的结果.

WITH_CLEANUP_FINISH
弹出异常类型和来自堆栈的’exit’函数调用的结果.

如果堆栈代表异常,and函数调用返回一个’true’值,这个信息被“删除”并用一个WHY_SILENCED替换,以防止END_FINALLY重新引发异常。(但非本地的遗骸仍将恢复。)

所有以下操作码都使用他们的论点.

STORE_NAMEnamei
实施name = TOS. namei是的索引name在属性co_names代码对象。编译器尝试使用STORE_FAST要么 STORE_GLOBAL如果可能的话
DELETE_NAME// (namei)
实施del name,其中nameico_names属性的索引代码对象.
UNPACK_SEQUENCE(count)
打开包装进count个别价值,放在stackright-to-left.
UNPACK_EX (counts
使用已加星标的目标实现赋值:将TOS中的iterable解包为单个值,其中值的总数可以小于iterable中的项目数量:其中一个新值将是allleftover项目的列表.

的低字节counts是列表值之前的值的数量,的高字节counts它之后的值的数量。由此产生的值被放在堆栈的右侧 – 左侧.

STORE_ATTRnamei
实现TOS.name = TOS1,其中nameico_names.
DELETE_ATTRnamei
中的名称索引实现del TOS.name,使用namei作为co_names.
STORE_GLOBALnamei)的索引
作为STORE_NAME,但将名称存储为全局
DELETE_GLOBALnamei
起到DELETE_NAME的作用,但是删除一个全局名称.
LOAD_CONST (consti
co_consts[consti]stack
LOAD_NAME(namei)
将与co_names[namei]相关的值推到堆栈上
BUILD_TUPLEcount
创建一个从堆栈中消耗count项目的元组,并将得到的元组推入堆栈.
BUILD_LIST (count
工作BUILD_TUPLE,但创建一个列表
BUILD_SET (count
工作BUILD_TUPLE,但创建一个集.
BUILD_MAP (count
将新的字典对象推入堆栈。Pops 2 * count item.so字典持有count条目:{..., TOS3: TOS2, TOS1: TOS}.

在版本3.5中更改:字典是从堆栈项创建的,而不是创建预先调整大小的字典来保存countitems.

BUILD_CONST_KEY_MAPcount
的版本BUILD_MAP专门用于恒定键。count值从堆栈中消耗。堆栈中的顶部元素包含按键元组

新版本3.6.

BUILD_STRING (count)
Concatenates count堆栈中的字符串并将结果字符串推到栈中.

新版本3.6.

BUILD_TUPLE_UNPACK (count)
Pops count从堆栈中迭代,将它们连接在一个元组中,然后推送结果。在tupledisplays中实现可迭代的解包(*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_UNPACKcount
这类似于BUILD_TUPLE_UNPACK,但推动列表而不是元组。在listdisplays中实现可迭代的解包[*x, *y, *z].

3.5版中的新功能

BUILD_SET_UNPACK (count)
这类似于BUILD_TUPLE_UNPACK,但推动了一个集合而不是元组。在setdisplays中实现可迭代的解包{*x, *y, *z}.

3.5版中的新功能

BUILD_MAP_UNPACK(count)
Pops count堆栈中的映射,将它们合并到一个字典中,然后推送结果。在dictionarydisplays中实现字典解包{**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更改:可调用的位置是通过向opcodeargument添加2而不是在参数的第二个字节中对其进行编码来确定的.

LOAD_ATTRnamei
用取代TOSgetattr(TOS, co_names[namei]).
COMPARE_OPopname
执行布尔运算。操作名称可以在cmp_op[opname].
IMPORT_NAMEnamei
中找到导入模块co_names[namei]。弹出TOS和TOS1并提供fromlistlevel __import__()。moduleobject被压入堆栈。当前的命名空间不受影响:对于正确的import语句,随后的STORE_FAST指令修改命名空间.
IMPORT_FROM (namei )
从TOS中找到的模块加载属性co_names[namei]。将得到的物体推到堆叠上,随后用STORE_FAST指令存放.
JUMP_FORWARD (delta
增加字节码计数器delta.
POP_JUMP_IF_TRUEtarget
如果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_ITERdelta
TOS是迭代器。调用它的__next__()方法。如果它产生一个新值,则将其推入堆栈(将迭代器置于下方)。如果迭代器指示它已用完,则弹出TOS,并且字节码计数器增加delta.
LOAD_GLOBALnamei
将名为co_names[namei]的全局加载到stack.
SETUP_LOOP (delta
将一个块推到块堆上。该块从当前指令开始,大小为delta bytes.
SETUP_EXCEPT(delta)
从try-except子句推送一个try块到块堆栈。delta指向第一个除了block.
SETUP_FINALLY (delta)
从try-except子句中将try块推到块堆栈上。delta指向最后一块
LOAD_FAST (var_num)
将当地的co_varnames[var_num]推到堆栈上
STORE_FASTvar_num
将TOS存储到本地co_varnames[var_num].
DELETE_FASTvar_num
删除本地co_varnames[var_num].
LOAD_CLOSUREi
推送引用到细胞的槽i中包含的细胞和自由变量的存储。如果co_cellvars[i]不是i的长度,变量的名称是co_cellvars。否则它是co_freevars[i -len(co_cellvars)].
LOAD_DEREFi
加载单元格的槽i中包含的单元格和自由变量存储。推送对象的引用单元格包含在堆栈上
LOAD_CLASSDEREFi)
很像LOAD_DEREF但是在查询单元格之前首先检查本地字典。这用于在classbodies中加载自由变量.

新版本3.4.

STORE_DEREF (i)
将TOS存入插槽中的单元格i的单元格和自由变量存储.
DELETE_DEREF (i)
清空单元格中包含的单元格i的单元格和自由变量存储。使用del声明

新版本3.2.

RAISE_VARARGS (argc)
发出异常。argc指示raise语句的参数个数,范围从0到3.处理程序将找回跟踪为TOS2,参数为TOS1,异常为TOS.
CALL_FUNCTION(argc)
使用位置参数调用可调用对象.argc表示位置参数的数量。堆栈顶部包含位置参数,右侧最右侧参数。参数下面是一个可调用的对象CALL_FUNCTION将所有参数和可调用对象弹出堆栈,使用这些参数调用可调用对象,并推送可调用对象返回的返回值.

更改版本3.6:此操作码仅用于具有位置参数的调用.

CALL_FUNCTION_KW(argc)
使用位置(如果有)和关键字参数调用可调用对象.argc表示位置和关键字参数的总数。堆栈中的top元素包含一个关键字参数名称元组.Below是对应于tuple.Below的顺序中的关键字参数,它们是位置参数,最右边的参数是ontop。参数下面是一个可调用的对象CALL_FUNCTION_KW将所有参数和可调用对象弹出堆栈,用这些参数调用可调用对象,并推送可调用对象返回的返回值.

版本3.6更改:关键字参数打包在元组而不是字典中,argc表示参数总数.

CALL_FUNCTION_EX (flags
使用可变的位置和关键字参数集调用可调用对象。如果设置了flags的最低位,则堆栈的顶部包含一个包含其他关键字参数的映射对象。这是一个包含位置参数和要调用的可调用对象的可迭代对象。BUILD_MAP_UNPACK_WITH_CALLBUILD_TUPLE_UNPACK_WITH_CALL可以用来合并多个映射对象和包含参数的迭代。在调用callable之前,映射对象和可迭代对象都是“解包”的,它们的内容分别作为关键字和位置参数传入.CALL_FUNCTION_EX弹出所有参数和离开堆栈的可调用对象,用这些参数调用可调用对象,并推送可调用对象返回的返回值.

新版本3.6.

LOAD_METHOD (namei)
从TOS对象加载名为co_names[namei]的方法。当解释器可以直接调用未绑定方法时,TOS弹出并且方法被推送.TOS将被self用作第一个参数(CALL_METHOD)。否则,NULL和方法被推(方法是绑定方法或其他).

版本3.7.

CALL_METHOD (argc)
新方法。argc是位置参数的数量。不支持关键字参数。此操作码设计用于LOAD_METHOD。位置参数位于堆栈的顶部。将它们放在堆栈中的LOAD_METHOD中描述的两个项目中。弹出所有这些项目并返回值.

新版本3.7.

MAKE_FUNCTIONargc
在堆栈上推送一个新的函数对象。从下到上,如果参数带有指定的标志值

  • 0x01按位置顺序的位置和位置或关键字参数的默认值元组
  • 0x02 a,则必须由consumestack组成值。关键字参数的字典’默认值
  • 0x04注释字典
  • 0x08包含自由变量单元格的元组,关闭
  • 与函数关联的代码(在TOS1)
  • 合格的名称的功能(在TOS)
BUILD_SLICEargc

推堆栈上的切片对象。argc必须是2或3.如果是2,slice(TOS1, TOS)被推;如果它是3,slice(TOS2, TOS1, TOS)被推。有关详细信息,请参阅slice()内置功能.

EXTENDED_ARG (ext )
前缀任何参数太大而不适合默认的twobytes的操作码。ext保存两个额外的字节,与后续的操作码的参数一起构成一个四字节的参数,ext是两个最重要的字节.
FORMAT_VALUE (flags
用于实现格式化文字字符串(f-strings)。Popsan可选fmt_spec从堆栈中,然后所需的value.flags解释如下:

  • (flags & 0x03) == 0x00value格式为-is.
  • (flags & 0x03) == 0x01:打电话给str()value格式化之前它
  • (flags & 0x03) == 0x02:打电话repr()value格式化之前它
  • (flags & 0x03) == 0x03:打电话ascii()value格式化之前它
  • (flags & 0x04) == 0x04:pop fmt_spec从堆栈和useit,否则使用空fmt_spec.

使用PyObject_Format()执行格式化。将结果推到堆栈上

新版本3.6.

HAVE_ARGUMENT
这不是一个操作码。它标识了不使用自己的参数的代码和分别代码的代码(< HAVE_ARGUMENT>= HAVE_ARGUMENT)的分界线.

在版本3.6中更改:现在每个指令都有一个参数,但操作码< HAVE_ARGUMENT忽略它。之前,只有操作码>= HAVE_ARGUMENT有一个参数.

 

Opcode集合

这些集合用于自动内省字节码指令:

dis.opname
操作名称序列,可索引使用bytecode.
dis.opmap
Dictionary将操作名称映射到bytecodes.
dis.cmp_op
所有比较操作名称的序列.
dis.hasconst
访问常量的字节码序列.
dis.hasfree
访问自由变量的字节码序列(请注意,此上下文中的’free’是指当前作用域中由内窥镜引用的名称或从此作用域引用的外部作用域中的名称。它会not包含引用到全局或内置范围).
dis.hasname
按名称访问属性的字节码序列.
dis.hasjrel
具有相对跳转目标的字节码的序列.
dis.hasjabs
有字节码的序列绝对跳转目标.
dis.haslocal
访问局部变量的字节码序列.
dis.hascompare
布尔运算的字节码序列.