A reference guide for disassembling Python bytecode.

Example:

>>> def test(value):
...     return len(value)
... 
>>> import dis
>>> dis.dis(test)
  2           0 LOAD_GLOBAL              0 (len)
              2 LOAD_FAST                0 (value)
              4 CALL_FUNCTION            1
              6 RETURN_VALUE

Explanation:

(1) (2) (3) (4) (5) (6) (7)
2 0 LOAD_GLOBAL 0 (len)
2 LOAD_FAST 0 (value)
4 CALL_FUNCTION 1
6 RETURN_VALUE

The columns returned are the following:

  1. The corresponding line number in the source code
  2. Optionally indicates the current instruction executed (when the bytecode comes from a frame object for example)
  3. A label which denotes a possible JUMP from an earlier instruction to this one
  4. The address in the bytecode which corresponds to the byte index (those are multiples of 2 because Python 3.6 use 2 bytes for each instruction, while it could vary in previous versions):
>>> code = test.__code__.co_code
>>> code
b't\x00|\x00\x83\x01S\x00'
>>> l = list(code)
>>> l
[116, 0, 124, 0, 131, 1, 83, 0]
>>> l[0]
116
>>> l[2]
124
>>> l[4]
131
>>> l[6]
83
  1. The instruction name (also called opname), each one is briefly explained in the dis module:
>>> dis.opname[116]
'LOAD_GLOBAL'
>>> dis.opname[124]
'LOAD_FAST'
>>> dis.opname[131]
'CALL_FUNCTION'
>>> dis.opname[83]
'RETURN_VALUE'
  1. The argument (if any) of the instruction which is used internally by Python to fetch some constants or variables, manage the stack, jump to a specific instruction, etc.
>>> test.__code__.co_names[0]
'len'
>>> test.__code__.co_varnames[0]
'value'
  1. The human-friendly interpretation of the instruction argument

Some examples for a bytecode operations:

>>> test.__code__
<code object test at 0x7f9905577e40, file "<stdin>", line 1>
>>> test.__code__.co_filename
'<stdin>'
>>> test.__code__.co_consts
(None,)
>>> test.__code__.co_varnames
('value',)
>>> test.__code__.co_names
('len',)
>>> test.__code__.co_consts
(None,)
>>> test.__code__.co_argcount
1
>>> test.__code__.co_code
b't\x00|\x00\x83\x01S\x00'
>>> list(test.__code__.co_code)
[116, 0, 124, 0, 131, 1, 83, 0]
>>> dis.opname[116]
'LOAD_GLOBAL'
>>> dis.opmap['LOAD_GLOBAL']
116