An interpreter is a program that reads your Python code line by line and executes it immediately.
Unlike compiled languages like C or Java (which convert the code into machine code before running), Python interprets your code at runtime.
🧠 Python is an interpreted, high-level, dynamically typed language.
🔁 Internal Flow of Python Code Execution
Let’s say you write a file called hello.py with the following content:
print("Hello, Python World!")When you run it using:
python hello.pyHere’s what really happens behind the scenes:
<div class="infographic-pyflow">
<style>
.infographic-pyflow {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--mono-font: 'IBM Plex Mono', 'SFMono-Regular', Menlo, monospace;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', system-ui, sans-serif;
box-sizing: border-box;
max-width: 640px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-pyflow[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.infographic-pyflow *, .infographic-pyflow *::before, .infographic-pyflow *::after { box-sizing: border-box; }
.infographic-pyflow .pf-wrap { padding: 0 clamp(1rem, 4vw, 2rem) 1.5rem; }
.infographic-pyflow h1 {
font-family: var(--display-font);
font-weight: 600;
font-size: clamp(1.6rem, 5vw, 2.1rem);
text-align: center;
margin: 1.5rem 0 0.25rem;
letter-spacing: -0.01em;
}
.infographic-pyflow .pf-sub {
text-align: center;
color: var(--ink-soft);
font-size: 0.88rem;
margin: 0 0 1.4rem;
}
.infographic-pyflow .pf-run-row { display: flex; justify-content: center; margin-bottom: 1.6rem; }
.infographic-pyflow .pf-run-btn {
font: inherit; font-size: 0.85rem; font-weight: 700;
background: var(--accent); color: #fff; border: none; border-radius: 4px;
padding: 0.55rem 1.2rem; cursor: pointer; display: inline-flex; align-items: center; gap: 0.4rem;
}
.infographic-pyflow .pf-run-btn:disabled { opacity: 0.5; cursor: default; }
/* vertical flow */
.infographic-pyflow .flow { display: flex; flex-direction: column; align-items: stretch; }
.infographic-pyflow .flow-arrow-v { display: flex; justify-content: center; padding: 0.15rem 0; }
.infographic-pyflow .flow-arrow-v svg { width: 20px; height: 26px; stroke: var(--line); fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; transition: stroke 0.25s; }
.infographic-pyflow .flow-arrow-v.is-active svg { stroke: var(--accent); }
.infographic-pyflow .flow-card {
background: var(--paper-alt);
border: 1px solid var(--line);
padding: 1rem 1.1rem;
cursor: pointer;
font: inherit;
color: var(--ink);
text-align: left;
display: grid;
grid-template-columns: 42px 1fr auto;
align-items: center;
gap: 0.9rem;
transition: border-color 0.2s, background 0.2s;
width: 100%;
}
.infographic-pyflow .flow-card.is-open,
.infographic-pyflow .flow-card.is-active {
border-color: var(--accent);
}
.infographic-pyflow .flow-card.is-active { background: var(--accent-soft); }
.infographic-pyflow .card-num {
font-family: var(--display-font); color: var(--accent); font-size: 1.25rem; line-height: 1;
}
.infographic-pyflow .card-title { font-weight: 700; font-size: 0.95rem; }
.infographic-pyflow .card-icon { width: 46px; height: 40px; }
.infographic-pyflow .card-icon svg { width: 100%; height: 100%; stroke: var(--ink-soft); fill: none; stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round; }
.infographic-pyflow .flow-card.is-open .card-icon svg,
.infographic-pyflow .flow-card.is-active .card-icon svg { stroke: var(--accent); }
.infographic-pyflow .card-detail {
grid-column: 2 / -1;
display: none;
font-size: 0.8rem;
color: var(--ink-soft);
line-height: 1.4;
margin-top: 0.6rem;
}
.infographic-pyflow .flow-card.is-open .card-detail { display: block; }
.infographic-pyflow .card-illustration { margin-top: 0.55rem; }
/* token chips (step 2 illustration) */
.infographic-pyflow .token-row { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.infographic-pyflow .token-chip {
font-family: var(--mono-font); font-size: 0.72rem; font-weight: 700;
padding: 0.2rem 0.45rem; border-radius: 3px; border: 1px solid var(--accent);
color: var(--accent); background: var(--accent-soft);
}
/* run/output panel — always a dark editor look */
.infographic-pyflow .pf-output { margin-top: 1.4rem; }
.infographic-pyflow .device {
--ed-bg: #1e1e1e; --ed-bar: #2d2d2d; --ed-text: #d4d4d4; --ed-soft: #8a8a8a; --ed-ok: #6fdc8c;
background: var(--ed-bg); border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
opacity: 0; max-height: 0; transition: opacity 0.3s ease;
}
.infographic-pyflow .device.is-visible { opacity: 1; max-height: 200px; }
.infographic-pyflow .device-bar {
display: flex; align-items: center; gap: 0.4rem;
background: var(--ed-bar); padding: 0.5rem 0.7rem; border-bottom: 1px solid #3a3a3a;
font-size: 0.72rem; color: var(--ed-soft); font-weight: 600;
}
.infographic-pyflow .device-bar .dot { width: 9px; height: 9px; border-radius: 50%; background: #5a5a5a; }
.infographic-pyflow .device-bar .dot:nth-child(1) { background: #ff5f56; }
.infographic-pyflow .device-body { padding: 0.8rem 0.9rem; font-family: var(--mono-font); font-size: 0.85rem; color: var(--ed-text); min-height: 60px; }
.infographic-pyflow .repl-line { display: flex; gap: 0.5rem; opacity: 0; animation: pf-fadein 0.3s ease forwards; }
@keyframes pf-fadein { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: translateY(0); } }
.infographic-pyflow .repl-line .p { color: var(--ed-ok); font-weight: 700; }
.infographic-pyflow .repl-line.out { color: #fff; font-weight: 600; }
@media (prefers-reduced-motion: reduce) {
.infographic-pyflow *, .infographic-pyflow *::before, .infographic-pyflow *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="pf-wrap">
<h1>What Happens When Python Runs</h1>
<p class="pf-sub">hello.py, from source to output. Tap a stage, or watch it run.</p>
<div class="pf-run-row">
<button class="pf-run-btn" id="pfRun">▶ Run hello.py</button>
</div>
<div class="flow">
<!-- 1 Source -->
<button class="flow-card" data-step="0">
<div class="card-icon">
<svg viewBox="0 0 46 40"><path d="M6,2 L26,2 L36,12 L36,38 L6,38 Z"/><path d="M26,2 L26,12 L36,12"/><text x="14" y="30" font-size="9" stroke="none" fill="currentColor">.py</text></svg>
</div>
<div class="card-title">Source Code</div>
<div class="card-num">01</div>
<div class="card-detail">
<div class="card-illustration">
<div class="token-chip" style="background:none;border:none;padding:0;color:var(--ink-soft);font-weight:400;">Your saved <strong>.py</strong> file — just text.</div>
</div>
</div>
</button>
<div class="flow-arrow-v" data-arrow="0"><svg viewBox="0 0 20 26"><path d="M10,2 V22 M4,16 L10,23 L16,16"/></svg></div>
<!-- 2 Tokenization -->
<button class="flow-card" data-step="1">
<div class="card-icon">
<svg viewBox="0 0 46 40"><rect x="2" y="14" width="10" height="12" rx="2"/><rect x="16" y="14" width="8" height="12" rx="2"/><rect x="28" y="14" width="8" height="12" rx="2"/><rect x="38" y="14" width="6" height="12" rx="2"/></svg>
</div>
<div class="card-title">Tokenization</div>
<div class="card-num">02</div>
<div class="card-detail">
<div class="card-illustration token-row">
<span class="token-chip">print</span>
<span class="token-chip">(</span>
<span class="token-chip">"Hello"</span>
<span class="token-chip">)</span>
</div>
</div>
</button>
<div class="flow-arrow-v" data-arrow="1"><svg viewBox="0 0 20 26"><path d="M10,2 V22 M4,16 L10,23 L16,16"/></svg></div>
<!-- 3 Parsing -->
<button class="flow-card" data-step="2">
<div class="card-icon">
<svg viewBox="0 0 46 40"><circle cx="23" cy="6" r="4"/><circle cx="10" cy="24" r="4"/><circle cx="36" cy="24" r="4"/><circle cx="23" cy="24" r="4"/><path d="M23,10 L10,20 M23,10 L23,20 M23,10 L36,20"/></svg>
</div>
<div class="card-title">Parsing → AST</div>
<div class="card-num">03</div>
<div class="card-detail">
Builds a tree of your code. Bad syntax errors out here.
</div>
</button>
<div class="flow-arrow-v" data-arrow="2"><svg viewBox="0 0 20 26"><path d="M10,2 V22 M4,16 L10,23 L16,16"/></svg></div>
<!-- 4 Compilation -->
<button class="flow-card" data-step="3">
<div class="card-icon">
<svg viewBox="0 0 46 40"><rect x="2" y="10" width="16" height="20" rx="2"/><path d="M22,20 H30 M26,15 L31,20 L26,25"/><rect x="34" y="10" width="10" height="20" rx="2"/><text x="35.5" y="22" font-size="7" stroke="none" fill="currentColor">01</text></svg>
</div>
<div class="card-title">Compilation</div>
<div class="card-num">04</div>
<div class="card-detail">
AST becomes bytecode, cached in <span style="font-family:var(--mono-font)">__pycache__/*.pyc</span>.
</div>
</button>
<div class="flow-arrow-v" data-arrow="3"><svg viewBox="0 0 20 26"><path d="M10,2 V22 M4,16 L10,23 L16,16"/></svg></div>
<!-- 5 PVM -->
<button class="flow-card" data-step="4">
<div class="card-icon">
<svg viewBox="0 0 46 40"><rect x="8" y="8" width="30" height="24" rx="2"/><rect x="15" y="15" width="16" height="10" rx="1"/><path d="M12,8 V2 M20,8 V2 M28,8 V2 M12,32 V38 M20,32 V38 M28,32 V38 M8,14 H2 M8,22 H2 M38,14 H44 M38,22 H44"/></svg>
</div>
<div class="card-title">Python Virtual Machine</div>
<div class="card-num">05</div>
<div class="card-detail">
Executes bytecode: memory, calls, exceptions, I/O — your program actually runs.
</div>
</button>
</div>
<div class="pf-output">
<div class="device" id="pfDevice">
<div class="device-bar"><span class="dot"></span><span class="dot"></span><span class="dot"></span> Terminal</div>
<div class="device-body" id="pfLog"></div>
</div>
</div>
</div>
<script>
(function () {
var root = document.currentScript.closest('.infographic-pyflow')
|| document.querySelector('.infographic-pyflow');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) root.setAttribute('data-theme', 'dark');
var cards = root.querySelectorAll('.flow-card');
var arrows = root.querySelectorAll('.flow-arrow-v');
var runBtn = root.querySelector('#pfRun');
var device = root.querySelector('#pfDevice');
var log = root.querySelector('#pfLog');
var playing = false;
function openCard(step) {
cards.forEach(function (c) {
var isThis = Number(c.dataset.step) === step;
c.classList.toggle('is-open', isThis);
});
}
cards.forEach(function (card) {
card.addEventListener('click', function () {
if (playing) return;
var step = Number(card.dataset.step);
var wasOpen = card.classList.contains('is-open');
openCard(wasOpen ? -1 : step);
});
});
function setActive(step) {
cards.forEach(function (c) {
c.classList.toggle('is-active', Number(c.dataset.step) === step);
});
arrows.forEach(function (a) {
a.classList.toggle('is-active', Number(a.dataset.arrow) < step);
});
}
function clearActive() {
cards.forEach(function (c) { c.classList.remove('is-active'); });
arrows.forEach(function (a) { a.classList.remove('is-active'); });
}
function playSequence() {
if (playing) return;
playing = true;
runBtn.disabled = true;
openCard(-1);
clearActive();
device.classList.remove('is-visible');
log.innerHTML = '';
var step = 0;
var total = cards.length;
function advance() {
if (step < total) {
setActive(step);
openCard(step);
step++;
setTimeout(advance, 650);
} else {
clearActive();
showOutput();
}
}
advance();
}
function appendLine(promptText, text, isOut, delay) {
setTimeout(function () {
var line = document.createElement('div');
line.className = 'repl-line' + (isOut ? ' out' : '');
var html = '';
if (promptText) html += '<span class="p">' + promptText + '</span>';
html += '<span>' + text + '</span>';
line.innerHTML = html;
log.appendChild(line);
}, delay);
}
function showOutput() {
device.classList.add('is-visible');
appendLine('$', 'python hello.py', false, 100);
appendLine('', 'Hello, Python World!', true, 550);
setTimeout(function () {
playing = false;
runBtn.disabled = false;
}, 900);
}
runBtn.addEventListener('click', playSequence);
})();
</script>
</div>🧩 Tokenization
Python first breaks your code into tokens (small meaningful chunks) like:
Keywords (
print)Identifiers
Symbols (
(),")Literals (
"Hello")
This is handled by Python’s lexer.
🧱 Parsing → AST (Abstract Syntax Tree)
Python checks the syntax of your code and constructs a tree-like structure called the AST.
Think of AST as a blueprint of your program.
If syntax is wrong (e.g. missing parenthesis), Python throws an error at this stage.
🔥 Compilation to Bytecode
Once the AST is ready, Python compiles it to bytecode — a low-level, platform-independent set of instructions that the Python interpreter understands.
Bytecode is stored as .pyc files in the __pycache__ folder.
__pycache__/hello.cpython-311.pyc✅ Bytecode is not machine code but is portable across systems where Python runs.
🧠 Execution by Python Virtual Machine (PVM)
Now the Python Virtual Machine takes over and executes the bytecode step by step.
This is where your program “actually runs.”
The PVM:
Allocates memory for variables
Manages function calls
Handles exceptions
Talks to OS for input/output
📦 Real-World Analogy
Imagine you are ordering food:
.py File = Your food order (instructions)
Lexer/Parser = The waiter breaking down your order into items
AST & Bytecode = The kitchen preparing your order
PVM = The chef making and serving it to you
Just like your food goes through steps before it reaches you, Python code goes through multiple stages before being executed.
⚠️ Why Understanding This Helps
Helps in debugging and understanding error messages (like syntax errors)
Lets you appreciate why Python is slower than compiled languages (it interprets on the fly)
Makes you aware of
__pycache__and.pycfiles
🧾 Recap:
Python code is read and executed line-by-line.
Internally, it goes through tokenization → parsing → bytecode compilation → PVM execution.
Python is both easy to write and intelligent internally.