The dis module in Python standard library provides various functions useful for analysis of Python bytecode by disassembling it into a human-readable form. This helps to perform optimizations. Bytecode is a version-specific implementation detail of the interpreter.
dis() function
The function dis() generates disassembled representation of any Python code source i.e. module, class, method, function, or code object.
>>> def hello(): print ("hello world") >>> import dis >>> dis.dis(hello) 2 0 LOAD_GLOBAL 0 (print) 3 LOAD_CONST 1 ('hello world') 6 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 9 POP_TOP 10 LOAD_CONST 0 (None) 13 RETURN_VALUE
Bytecode analysis API is defined in Bytecode class. Its constructor returns Bytecode object which is having following methods to analyse the bytecode
Bytecode()
This is the constructor. Analyse the bytecode corresponding to a function, generator, method, string of source code, or a code object. This is a convenience wrapper around many of the functions
>>> string=dis.Bytecode(hello) >>> for x in string: print (x) Instruction(opname = 'LOAD_GLOBAL', opcode = 116, arg = 0, argval = 'print', argrepr = 'print', offset = 0, starts_line = 2, is_jump_target = False) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 1, argval = 'hello world', argrepr = "'hello world'", offset = 3, starts_line = None, is_jump_target = False) Instruction(opname = 'CALL_FUNCTION', opcode = 131, arg = 1, argval = 1, argrepr = '1 positional, 0 keyword pair', offset = 6, starts_line = None, is_jump_target = False) Instruction(opname = 'POP_TOP', opcode = 1, arg = None, argval = None, argrepr = '', offset = 9, starts_line = None, is_jump_target = False) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 0, argval = None, argrepr = 'None', offset = 10, starts_line = None, is_jump_target = False) Instruction(opname = 'RETURN_VALUE', opcode = 83, arg = None, argval = None, argrepr = '', offset = 13, starts_line = None, is_jump_target = False)
code_info()
This function returns information of Python code object.
>>> dis.code_info(hello) "Name: hello\nFilename: <pyshell#2>\nArgument count: 0\nKw-only arguments: 0\nNumber of locals: 0\nStack size: 2\nFlags: OPTIMIZED, NEWLOCALS, NOFREE\nConstants:\n 0: None\n 1: 'hello world'\nNames:\n 0: print"
show_code()
This function prints detailed code information of Python module, function or class.
>>> dis.show_code(hello) Name: hello Filename: <pyshell#2> Argument count: 0 Kw-only arguments: 0 Number of locals: 0 Stack size: 2 Flags: OPTIMIZED, NEWLOCALS, NOFREE Constants: 0: None 1: 'hello world' Names: 0: print
disassemble()
This function disassembles a code object and gives output divided in the following columns −
the line number, for the first instruction of each line
the current instruction, indicated as -->,
a labelled instruction, indicated with >>,
the address of the instruction,
the operation code name,
operation parameters, and
interpretation of the parameters in parentheses.
>>> codeInString = 'a = 5\nb = 6\nsum = a + b \ nprint("sum = ",sum)' >>> codeObejct = compile(codeInString, 'sumstring', 'exec') >>> dis.disassemble(codeObejct)
Output
1 0 LOAD_CONST 0 (5) 3 STORE_NAME 0 (a) 2 6 LOAD_CONST 1 (6) 9 STORE_NAME 1 (b) 3 12 LOAD_NAME 0 (a) 15 LOAD_NAME 1 (b) 18 BINARY_ADD 19 STORE_NAME 2 (sum) 4 22 LOAD_NAME 3 (print) 25 LOAD_CONST 2 ('sum =') 28 LOAD_NAME 2 (sum) 31 CALL_FUNCTION 2 (2 positional, 0 keyword pair) 34 POP_TOP 35 LOAD_CONST 3 (None) 38 RETURN_VALUE
get_instructions()
This function returns an iterator over the instructions in the supplied function, method, source code string or code object. The iterator generates a series of Instruction named tuples giving the details of each operation in the supplied code.
>>> it=dis.get_instructions(code) >>> for i in it: print (i) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 0, argval = <code object hello at 0x02A9BA70, file "<disassembly>", line 2>, argrepr = '<code object hello at 0x02A9BA70, file "<disassembly>", line 2>', offset = 0, starts_line = 2, is_jump_target = False) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 1, argval = 'hello', argrepr = "'hello'", offset = 3, starts_line = None, is_jump_target = False) Instruction(opname = 'MAKE_FUNCTION', opcode = 132, arg = 0, argval = 0, argrepr = '', offset = 6, starts_line = None, is_jump_target = False) Instruction(opname = 'STORE_NAME', opcode = 90, arg = 0, argval = 'hello', argrepr = 'hello', offset = 9, starts_line = None, is_jump_target = False) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 2, argval = None, argrepr = 'None', offset = 12, starts_line = None, is_jump_target = False) Instruction(opname = 'RETURN_VALUE', opcode = 83, arg = None, argval = None, argrepr = '', offset = 15, starts_line = None, is_jump_target = False)
The functions information is in the form of tuple like object with the parameters as shown below −
Instruction | Details for a bytecode operation |
---|---|
opcode | numeric code for operation, corresponding to the opcode values listed below and the bytecode values in the Opcode collections. |
opname | human readable name for operation |
arg | numeric argument to operation (if any), otherwise None |
argval | resolved arg value (if known), otherwise same as arg |
argrepr | human readable description of operation argument |
offset | start index of operation within bytecode sequence |
starts_line | line started by this opcode (if any), otherwise None |
is_jump_target | True if other code jumps to here, otherwise False |