Definition
Every language has to answer one basic question: how do you know where a group of instructions begins and ends? Most answer with markers, braces in C or JavaScript, keywords elsewhere. Because those markers cannot be read at a glance, lines are also shifted to the right so the structure shows. Two systems end up living side by side, one for the machine and one for the eye, and nothing guarantees they tell the same story.
Python removes that duplicate: the shift you see is the one the interpreter reads. Indentation is that shift at the start of a line, and it is what delimits blocks. Elsewhere it belongs to presentation and the compiler ignores it; here it is part of the syntax, exactly like a semicolon in other languages. Indenting badly does not make the code less pretty: it makes it wrong.
A tiny example is enough to see the mechanism. Look at the last line above all, the only one back against the left margin.
if balance > 0:
print("Credit available") # inside the if block
send_confirmation() # inside the if block as well
print("End of processing") # back at the margin: outside the ifThe two shifted lines belong to the if and only run when the condition is true. The last one, back at the margin, runs in every case. No keyword closes the block: the return to the margin is the only end signal.
Which brings up the question that matters: what happens when you are one step off? Move send_confirmation back to the margin and the file stays perfectly valid. Python reports nothing, the program runs, and the confirmation now goes out for overdrawn accounts too. The whole danger sits there: a wrong shift does not crash anything, it changes what the program means.
Four spaces, and never a tab
The language imposes no particular width: it only requires the shift to stay regular inside a single block. Three spaces work, eight work, a tab works, as long as you do not change your mind halfway through.
The convention is far stricter, and PEP 8 is what sets it: four spaces per level, never a tab. This is not a matter of taste. Python code travels between editors, terminals, web interfaces and messaging apps that do not display a tab at the same width, while a space is a space everywhere. So set your editor to turn the tab key into four spaces: it is the first setting to check when joining a Python project.
Mixing spaces and tabs is the nastiest error in the language, because it is invisible. Two lines can look aligned to the pixel while one starts with a tab and the other with four spaces. Python rejects the file with a TabError, and the eye sees nothing to fix. Reindent the whole area rather than hunt for the offending character.
Everything that opens a block
Once the principle is accepted, the grammar comes down to a single observation: a line ending with a colon announces a block, indented just below it. The colon opens, the indentation carries the content, the return to the margin closes.
Here are the structures concerned, with what their block holds in each case.
| Structure | What it holds |
|---|---|
if, elif, else | The code subject to the condition |
for, while | The body of the loop |
| def, class | The body of the function or of the class |
try, except, finally | The watched code and its recovery |
| with | The code running inside the context |
A block can never stay empty. If the body of a function is not written yet, the pass statement holds the place and keeps the file valid. A comment would not do the job: Python expects a statement at that spot, and a comment is not one.
The regularity required stops at the boundaries of a block. A file indented with two spaces and another with four live together in the same project without a word of complaint: it is human reading that suffers, not the interpreter. A formatter such as black settles the question by rewriting the whole project at the same width.
What the constraint buys you
This obligation looks like an oddity when you arrive from another language, and it still renders two services that only show with use. The first: all Python code in the world looks alike. No debate about brace placement, no house style to absorb when joining a project, no configuration file to negotiate with a team.
The second is visible to the naked eye, since the complexity of a piece of code takes a shape. A function whose body runs five levels deep draws a staircase moving away from the margin, and that drawing announces the problem before a single line has been read. Here, the structure of a program and its appearance can no longer diverge, which makes indentation a reading tool as much as a syntax rule.
Frequently asked questions
How many spaces should be used?
Four per level, the universal convention from PEP 8. Two or eight work technically, but no serious project departs from it, and every automatic formatter applies four without asking. One case alone justifies aligning otherwise: picking up existing code, where following the width already in place beats mixing two conventions.
Where does the "unexpected indent" error come from?
From a line shifted when no line above it opened a block, most often after a copy and paste between two files. Python raises an IndentationError and gives the exact line number; the fix almost always consists of bringing the reported line back to the level of the one before it. Its opposite, "expected an indented block", reports a line ending with a colon and nothing underneath.
Can everything be written on one line to avoid indentation?
The language allows it for a single-statement block, such as if x: return 0, but readability suffers as soon as the line grows, and formatters rewrite it across two lines. That writing should be kept for the shortest cases only. Picking up the right formatting habits from the very first programs saves having to unlearn them later, and that is where our Python course begins.