Style & Idioms
Advanced · 18 min read · ▶ live playground · ✦ checkpoint
Two programs can give the same answer, and one can still feel expensive to read. Professional Python is not fancy Python; it is code another tired human can trust quickly.
PEP 8 is shared handwriting
PEP 8 is Python Enhancement Proposal 8, the official Python style guide for formatting and naming. A style guide is a shared set of choices for how code should look, like shared handwriting on a team: it does not change the message, but it makes the message easier to read.
PEP 8 covers many details, but the beginner-level habit is smaller: use four spaces for indentation, put spaces around most operators, keep names readable, and prefer lines that a person can scan without dragging their eyes across the page.
def total_with_tip(meal_total, tip_rate):
tip = meal_total * tip_rate
return meal_total + tip
meal_total = 24.50
print(f"Total: ${total_with_tip(meal_total, 0.18):.2f}")Total: $28.91
The blank line before meal_total is not magic. The spaces around = and * do not change the result. They change how fast your eyes find the parts.
PEP 8 is a convention, not a police badge. There are moments where a long URL, a table-like list, or an old project style asks for a practical exception. The professional move is to know the rule, keep the file consistent, and break the rule only when readability wins.
The Zen of Python in practice
The Zen of Python is PEP 20, a short list of Python design principles you can print with import this in a Python REPL. Treat it as pressure you apply while choosing between two working versions.
Three lines matter every week:
- "Readability counts" means the reader's time is part of the cost.
- "Explicit is better than implicit" means code should show the important idea instead of hiding it in cleverness.
- "Simple is better than complex" means fewer moving parts usually beat a more impressive shape.
Watch those lines guide a tiny decision:
orders = ["tea", "coffee", "tea", "juice", "tea"]
tea_count = orders.count("tea")
if tea_count >= 3:
print(f"Restock tea: {tea_count} orders")
else:
print("Tea supply is fine")Restock tea: 3 orders
You could squeeze that into one dense expression. You could also loop by hand and update a counter. This version says the idea out loud: count the tea orders, then decide whether to restock.
That is the practical Zen: not shorter at any cost, not longer to look serious, just clear pressure on the shape of the code.
Try it - make the names carry the story
Run this once. Then rename bonus_points to curve_points, change the scores, and see how much the code explains itself without extra comments.
Naming is design
A good name is not decoration. It is a small design choice. The name tells the reader what a value means, what a function promises, or what kind of object a class builds.
Python already gave you the main naming conventions in variables and memory. In professional code, you apply them with more care:
- Use
snake_casefor variables and functions:final_score,load_scores. - Use
CapWords, names made by capitalizing each word and joining them, for classes:ScoreCard,LibraryItem. - Use
ALL_CAPSfor constants by convention:MAX_ATTEMPTS. - Avoid names that only describe the type:
score_by_playerbeatsscore_dict.
players = ["Mina", "Ravi", "Noor"]
scores = [82, 91, 67]
for player, score in zip(players, scores):
if score >= 70:
print(f"{player}: ready")Mina: readyRavi: ready
player and score are plain, but they are doing work. They let you read the loop as a sentence: for each player and score, print who is ready.
Be careful with names that lie. valid_scores should not hold invalid scores. total should not be an average. A wrong name is worse than a short name because it sends the reader in the wrong direction.
Idioms beat anti-patterns
An idiom is the expected local way to express a common idea in a language, like saying "good morning" instead of translating each word from another language. An anti-pattern is a common-looking habit that causes avoidable trouble.
Pythonic code is clear Python that uses Python's expected idioms. It is not a contest to use the newest feature.
This is Pythonic because it uses tools that match the problem:
daily_scores = [88, 94, 71, 100]
high_scores = [score for score in daily_scores if score >= 90]
for position, score in enumerate(high_scores, start=1):
print(f"#{position}: {score}")#1: 94#2: 100
The list comprehension is a compact list-building expression, and here it says "make a list of high scores." enumerate() says "give me each item plus its position." Those are idioms you have already learned, and they keep the job visible.
Common anti-patterns are usually not syntax errors. They run, which makes them sneakier:
- Looping with
range(len(items))when you only need each item. - Building a string with repeated
+inside a loop whenjoin()says the job directly. - Catching every exception with bare
except:, anexcept:line with no specific exception type, when you know the specific problem. - Using a list when a set would make membership checks, tests for whether an item is present with
in, clearer and faster.
You will not memorize every idiom at once. You grow them the same way you grow vocabulary: read good code, notice repeated shapes, and ask whether your version says the same job in a way Python readers expect.
Checkpoint
Answer all three to mark this lesson complete
Clean style makes code easier to enter. The next step is making code easier to explain, so documentation and comments help the reader without repeating what the code already says.