Python bytecode is the intermediate representation Python compiles source code into before execution. The dis module lets you inspect bytecode instructions, showing exactly what operations Python executes. Understanding bytecode helps you optimize hot paths, debug performance issues, and understand Python's execution model.
Use bytecode inspection to understand how Python executes your code, identify performance bottlenecks, or verify compiler optimizations.
This example shows bytecode inspection with the dis module.
# run: python3 bytecode.py # description: inspecting bytecode with dis module import dis def simple_add(a, b): return a + b print("Bytecode for simple_add:") dis.dis(simple_add) print("\n" + "="*60 + "\n") # More complex function def factorial(n): if n <= 1: return 1 return n * factorial(n - 1) print("Bytecode for factorial:") dis.dis(factorial) print("\n" + "="*60 + "\n") # List comprehension vs loop def using_loop(): result = [] for i in range(10): result.append(i * 2) return result def using_comprehension(): return [i * 2 for i in range(10)] print("Loop version:") dis.dis(using_loop) print("\nList comprehension version:") dis.dis(using_comprehension) print("\n" + "="*60 + "\n") # Inspect bytecode of expressions code = "x = 1; y = 2; z = x + y" print(f"Bytecode for: {code}") dis.dis(compile(code, '<string>', 'exec')) print("\n" + "="*60 + "\n") # Inspect bytecode object func = lambda x: x * 2 print(f"Code object: {func.__code__}") print(f"Bytecode: {func.__code__.co_code}") print(f"Variable names: {func.__code__.co_varnames}") print(f"Constants: {func.__code__.co_consts}") print(f"Argument count: {func.__code__.co_argcount}") print("\nDisassembly:") dis.dis(func)
Inspecting functions:
dis.dis(func): print bytecode for functiondis.dis(lambda x: x+1): works on lambdas toodis.dis(code_object): works on code objectsInspecting classes and methods:
dis.dis(ClassName.method): method bytecodedis.dis(ClassName): all methods in class (Python 3.11+)Bytecode for strings:
compile(code_str, 'filename', 'exec'): compile string to code objectdis.dis(code_object): inspect compiled codeCode object introspection:
func.__code__: code object for functioncode.co_varnames: local variable namescode.co_consts: constants used in functioncode.co_names: names used (globals, attributes)code.co_argcount: number of argumentscode.co_code: raw bytecode bytesCommon bytecode instructions:
LOAD_CONST: load constant onto stackLOAD_FAST: load local variableLOAD_GLOBAL: load global variableBINARY_OP: binary operation (+, -, *, etc.)CALL_FUNCTION: call functionRETURN_VALUE: return from functionPOP_TOP: discard top of stackJUMP_IF_FALSE_OR_POP: conditional jumpPerformance insights:
When to inspect bytecode:
Limitations:
Python version differences:
sys.version_info if you need version-specific behavior