Compiler vs interpreter in one paragraph
A compiler translates a whole program into another form (usually machine code) before it runs; you then execute the result. An interpreter reads and executes the program directly, statement by statement, while it runs. C and Rust are compiled; shell scripts are interpreted. Python sits in between, and that is why the question keeps coming up.
What actually happens when you run a Python file
- The source text is parsed into an abstract syntax tree.
- The tree is compiled to bytecode — a compact, platform-independent instruction set for Python's virtual machine.
- The bytecode is interpreted by the CPython virtual machine, which executes each instruction.
So Python is compiled (to bytecode) and then interpreted (the bytecode). You can see the bytecode yourself:
import dis
def add(a, b):
return a + b
dis.dis(add)Those LOAD_FAST and BINARY_ADD lines are what the interpreter executes. This works in the Coding Python app too — it is a real CPython.
What .pyc files and __pycache__ are
When you import a module, CPython saves its compiled bytecode as a .pyc file in a __pycache__ folder so it does not need to recompile next time. They are a cache, safe to delete, and not a way to hide source code (they can be decompiled easily). The main script you run directly is compiled in memory and not cached.
Why the compile step matters to you
- SyntaxError happens before anything runs. Because the whole file is compiled first, a typo on line 200 stops line 1 from executing. Runtime exceptions (
NameError,TypeError) only appear when that line is reached. - Python is slower than C for tight loops because each bytecode instruction is dispatched by the VM. It is fast enough for the vast majority of programs, and libraries like NumPy do the heavy lifting in C.
- Portability. The same source runs on Windows, macOS, Linux and Android because the VM is what gets ported, not your code.
Other Python implementations
| Implementation | Approach | Use case |
|---|---|---|
| CPython | Bytecode + interpreter (reference implementation) | Everything; what runs in the Coding Python app |
| PyPy | JIT compiler to machine code at runtime | Long-running CPU-bound code, often 4–10× faster |
| Cython | Compiles annotated Python to C extensions | Speeding up hot loops in libraries |
| Nuitka | Ahead-of-time compiler to C | Standalone executables |
| MicroPython | Small interpreter for microcontrollers | ESP32, Raspberry Pi Pico |
Recent CPython versions (3.11+) also added a specialising adaptive interpreter and, experimentally, a JIT, so the "interpreted equals slow" reputation is fading.
So what is a 'Python compiler app'?
In everyday language "Python compiler" has come to mean "a place I can type Python and run it". An app that calls itself a Python compiler is an interpreter with an editor around it — and that is fine, because the compile-to-bytecode step happens inside it exactly as on a computer. What matters when choosing one is whether it runs code on the device or ships it to a server; the Python compiler for Android guide explains the difference.
Frequently asked questions
Is Python a compiled or interpreted language?
Both. CPython compiles source to bytecode and then interprets that bytecode on a virtual machine. Informally it is called an interpreted language.
Can Python be compiled to an exe?
Tools like PyInstaller and Nuitka bundle the interpreter and your bytecode (or compiled C) into a standalone executable. The code is still run by a Python runtime inside.
Why is Python slower than C?
Bytecode is executed by a VM with dynamic type checks at every operation, whereas C compiles to native instructions with types resolved in advance. For most applications the difference does not matter.
Is a Python compiler app really a compiler?
It is an interpreter with an editor. The name is marketing shorthand for 'write and run Python here'; the actual compile-to-bytecode step still happens inside it.