When you type python hello.py, a few things happen before the first line of your code actually runs. Knowing this process helps you understand error messages, pick the right Python version, and avoid confusion about why some mistakes are caught before any output appears.
This article follows the write and run your first Python program guide. You do not need to memorize every detail here. The goal is a working mental model.
The big picture: four steps
Python runs your code in four stages:
- Read -- Python reads your
.pyfile from disk. - Parse -- Python checks the syntax and builds a tree structure.
- Compile -- Python converts the tree into bytecode.
- Execute -- The Python Virtual Machine runs the bytecode.
If stage 2 or 3 finds an error, Python reports it and stops. None of your code runs. That is why you sometimes see a SyntaxError before any print() output.
Step 1: Read the source file
Python opens hello.py and reads it as text. If the file does not exist or Python cannot read it, you get an error immediately:
python: can't open file 'hello.py': [Errno 2] No such file or directoryThis happens before any Python code is processed. The interpreter still needs to find the file.
Python also checks for an encoding declaration. By default, Python 3 source files use UTF-8 encoding. If your file contains a special encoding comment like # -*- coding: latin-1 -*- on line 1 or 2, Python uses that instead.
Step 2: Parse into a syntax tree
Python reads your code and builds an Abstract Syntax Tree (AST). This is a structured representation of your program that the compiler can work with.
During parsing, Python catches syntax errors. If you write:
print("Hello"Python sees the missing closing parenthesis and reports:
SyntaxError: '(' was never closedNo output appears because parsing failed before execution started. This is useful: Python tells you about structural problems before wasting time running partial code.
The AST represents every element of your program: function definitions, loops, assignments, expressions. You can see the AST yourself with the ast module:
import ast
print(ast.dump(ast.parse("x = 1 + 2"), indent=2))But for daily coding, you do not need to inspect the AST. Just know it exists between your source code and the compiled output.
Step 3: Compile to bytecode
Python converts the AST into bytecode. Bytecode is a low-level, platform-independent set of instructions that the Python Virtual Machine understands.
Bytecode is not machine code for your CPU. It is a middle layer that makes Python programs portable. The same .py file can run on Windows, macOS, and Linux because the bytecode is the same on every platform.
Python stores compiled bytecode in a __pycache__ folder as .pyc files. You might see this folder appear in your project directory. Python uses these cached files to skip recompilation when the source file has not changed, which makes subsequent runs faster.
You can see bytecode with the dis module:
import dis
dis.dis("x = 1 + 2")This prints something like:
0 0 RESUME 0
2 LOAD_CONST 0 (3)
4 STORE_NAME 0 (x)
6 RETURN_CONST 1 (None)You do not need to understand these instructions as a beginner. The key point is that Python compiles your code into a compact, efficient form before running it.
Step 4: Execute on the Python Virtual Machine
The Python Virtual Machine (PVM) reads the bytecode and executes each instruction in order. This is the part that actually runs your print() calls, calculates 3 + 4, and assigns variables.
The PVM is a loop that:
- Reads the next bytecode instruction.
- Performs the operation (load a value, call a function, jump to another instruction).
- Moves to the next instruction.
This continues until all instructions are processed or an error occurs at runtime.
Runtime errors happen during this stage. Unlike syntax errors, runtime errors only appear when that specific line executes. For example:
print("Starting")
x = 1 / 0 # ZeroDivisionError
print("Done")The output is:
Starting
Traceback (most recent call last):
...
ZeroDivisionError: division by zero"Starting" prints because the error happens on line 2. "Done" never prints because the program stops at the error.
CPython and other implementations
The process described above is how CPython works. CPython is the default Python implementation written in C, and it is what you download from Python.org. At publication time in July 2026, CPython 3.14.6 is the latest stable release, with 3.15 in pre-release.
Other Python implementations exist:
- PyPy uses a Just-In-Time (JIT) compiler that can make some programs run much faster.
- Jython runs Python on the Java Virtual Machine.
- IronPython runs Python on the .NET runtime.
As a beginner, stick with CPython. It is the most widely used implementation and has the most learning resources. The other implementations are for specific needs that you will recognize later if they matter to you.
The Python interactive shell
There is a second way to run Python code: the interactive shell, also called the REPL (Read-Eval-Print Loop). Open it by typing python (or python3) with no filename:
$ python
Python 3.14.6 (main, Jun 10 2026, 10:00:00)
[Clang 17.0.0 (clang-1700.0.13.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>Type a Python statement at the >>> prompt and press Enter. Python reads, compiles, and runs that single statement immediately:
>>> print("Hello from the REPL!")
Hello from the REPL!
>>> 3 + 4
7The REPL is great for quick experiments and checking small pieces of code. But for anything you want to save and reuse, write it in a .py file and run that instead. Files are the normal way to build Python programs.
Why this matters for beginners
You do not need to understand bytecode or the AST to write useful Python programs. But knowing these four stages helps in three practical ways:
-
Syntax errors vs runtime errors. A syntax error means Python could not parse your file. No code ran. A runtime error means parsing succeeded but something went wrong during execution. The distinction helps you read error messages.
-
The
__pycache__folder is normal. When you see a__pycache__folder appear near your.pyfiles, it is Python storing compiled bytecode. You can ignore it or add it to.gitignore. It is not something you created by mistake. -
Python is not magic. When you type
python hello.py, a clear chain of events happens every time. There is a program reading your file, checking it, compiling it, and running it. Knowing this demystifies the process.
Now that you understand how Python runs your code, you may want to install third-party packages to extend what your programs can do, create your first Python project with multiple files, or set up a virtual environment for isolated dependencies. When you are ready to learn the language itself, start with Python syntax and indentation.
Rune AI
Key Insights
Python compiles source to bytecode before running anything; Syntax errors are caught at compilation time, before execution begins; The Python Virtual Machine runs bytecode instruction by instruction; CPython is the default implementation from Python.org.
Frequently Asked Questions
Is Python compiled or interpreted?
What is the Python interpreter?
Does Python run my code line by line?
What is CPython?
Conclusion
Understanding how Python runs your code helps you read error messages, debug problems, and write more efficient programs. The compilation step catches syntax before anything runs, and the bytecode execution loop makes Python portable.
More in this topic
Create and Assign Variables in Python
Learn every way to create and assign variables in Python, from basic single assignment to expressions, type hints, and practical patterns beginners use every day.
Python Variable Naming Rules
Learn Python's variable naming rules, including allowed characters, reserved keywords, PEP 8 conventions, and how to choose names that make your code readable.
Python Variables Explained
Understand what Python variables are, how they store and reference data, and why Python's variable model is different from other programming languages.