# Python Bytecode

Python is an interpreted language, but it also involves a compilation step. Python source code (`.py`) is first compiled into **bytecode**, which is a low-level, platform-independent set of instructions. This bytecode is then executed by the **Python Virtual Machine (PVM)**.

## The Compilation Process

1.  **Source Code**: You write Python code in `.py` files.
2.  **Bytecode**: When you run the program, Python compiles the source code into bytecode. This bytecode is often cached in `.pyc` files inside the `__pycache__` directory to speed up subsequent loads.
3.  **PVM**: The Python Virtual Machine reads the bytecode and executes the corresponding machine code instructions on your computer's CPU.

## Viewing Bytecode

You can inspect the bytecode of Python functions or modules using the built-in `dis` module (Disassembler).

```python
import dis

def add(a, b):
    return a + b

dis.dis(add)
```

**Output Example:**

```text
  4           0 LOAD_FAST                0 (a)
              2 LOAD_FAST                1 (b)
              4 BINARY_ADD
              6 RETURN_VALUE
```

For more details on the `dis` module, see [[programming/python/dis-module]].

## Understanding Instructions

Each line in the disassembly output represents a bytecode instruction:

*   **Line Number**: The line number in the original source code.
*   **Address**: The byte offset of the instruction in the bytecode sequence.
*   **Opcode**: The name of the operation (e.g., `LOAD_FAST`, `BINARY_ADD`).
*   **Argument**: The argument for the operation, if any.

## Code Objects

Bytecode is stored inside **code objects**. Every function in Python has a `__code__` attribute that holds its code object.

```python
def my_func():
    pass

print(my_func.__code__)
# Output: <code object my_func at ...>

print(my_func.__code__.co_code)
# Output: b'd\x00S\x00' (The raw bytecode bytes)
```

[[programming/python/python]]