๐Ÿ

A language tour

The Readability of Python

Code that fits in your mind. A language that gets out of the way and lets you think about the problem.

scroll

01 โ€” Readability

Code as executable prose

Guido van Rossum designed Python to be read as much as it is written. Indentation isn't just style โ€” it's syntax. The structure of the code mirrors the structure of the thought.

"Readability counts. Special cases aren't special enough to break the rules. If the implementation is hard to explain, it's a bad idea."

โ€” The Zen of Python (PEP 20), Tim Peters
readable.py
# Python reads close to plain English
fruits = ["apple", "banana", "cherry"]

if "banana" in fruits:
    print("We have bananas.")

# Chained comparisons โ€” unlike most languages
age = 25
if 18 <= age < 65:
    print("Working age.")

# Ternary that flows like a sentence
label = "adult" if age >= 18 else "minor"

# Unpacking โ€” name your data, not your indices
first, *rest = fruits
print(first)   # โ†’ apple
print(rest)    # โ†’ ['banana', 'cherry']

Chained comparisons like 18 <= age < 65 mirror mathematical notation โ€” Python trusts you to think naturally.


02 โ€” Comprehensions

Data transformation in one breath

List comprehensions are one of Python's most celebrated features โ€” a compact syntax for building new collections from existing ones. They eliminate the boilerplate of an append loop while remaining completely readable.

comprehensions.py
# The long way
squares = []
for n in range(10):
    squares.append(n ** 2)

# The Python way โ€” reads like set-builder notation
squares = [n ** 2 for n in range(10)]

# Add a condition
evens = [n for n in range(20) if n % 2 == 0]

# Dict comprehension โ€” same idea, different brackets
words = ["hello", "world", "python"]
lengths = {w: len(w) for w in words}
# โ†’ {'hello': 5, 'world': 5, 'python': 6}

# Generator โ€” same syntax, lazy evaluation, no memory cost
total = sum(n ** 2 for n in range(1_000_000))

The generator expression in the last line sums a million squares without ever holding them all in memory โ€” lazy by default.


03 โ€” Decorators

Functions that wrap functions

A decorator is just a function that takes a function and returns a new one. But the @ syntax turns this into something that reads like an annotation โ€” a clear, reusable way to add behaviour without touching the original code.

decorators.py
import time
from functools import wraps, cache

def timer(func):
    """Decorator: measure how long a function takes."""
    @wraps(func)
    def wrapper(*args, **kwargs):
        start  = time.perf_counter()
        result = func(*args, **kwargs)
        end    = time.perf_counter()
        print(f"{func.__name__} took {end - start:.4f}s")
        return result
    return wrapper

# The @ line reads: "timer-ify this function"
@timer
def crunch(n):
    return sum(i * i for i in range(n))

crunch(1_000_000)
# โ†’ crunch took 0.0842s

# Stack decorators โ€” they compose
@timer
@cache
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

Stacking @cache under @timer memoizes the recursive calls โ€” you compose cross-cutting concerns without touching business logic.


04 โ€” Context Managers

Resources that clean up themselves

The with statement is Python's answer to the question: "how do you guarantee cleanup?" It wraps a block with setup and teardown โ€” and the language guarantees the teardown runs, no matter what happens inside.

context_managers.py
# Files โ€” the classic case
with open("data.txt", "r") as f:
    contents = f.read()
# f.close() was called automatically โ€” even if read() raised

# Multiple resources, one line
with open("src.txt") as src, open("dst.txt", "w") as dst:
    dst.write(src.read())

# Build your own with contextlib
from contextlib import contextmanager

@contextmanager
def timer_block(label):
    start = time.perf_counter()
    yield                        # your code runs here
    elapsed = time.perf_counter() - start
    print(f"[{label}] {elapsed:.3f}s")

with timer_block("matrix multiply"):
    result = heavy_computation()
# โ†’ [matrix multiply] 0.217s

yield inside a @contextmanager splits setup from teardown at a single point โ€” everything before is enter, everything after is exit.


05 โ€” Dataclasses & Types

Structure without the boilerplate

Python's dataclasses generate __init__, __repr__, and __eq__ from a simple field declaration. Pair them with type hints and you get self-documenting, editor-friendly code โ€” without sacrificing Python's flexibility.

dataclasses.py
from dataclasses import dataclass, field
from typing import ClassVar

@dataclass
class Album:
    title:    str
    artist:   str
    year:     int
    tracks:   list[str] = field(default_factory=list)
    genre:    ClassVar[str] = "Unknown"

    def summary(self) -> str:
        return f"{self.artist} โ€” {self.title} ({self.year})"

# __init__, __repr__, and __eq__ are generated for free
album = Album(
    title  = "Kind of Blue",
    artist = "Miles Davis",
    year   = 1959,
    tracks = ["So What", "Freddie Freeloader", "Blue in Green"],
)

print(album.summary())
# โ†’ Miles Davis โ€” Kind of Blue (1959)
print(album)
# โ†’ Album(title='Kind of Blue', artist='Miles Davis', year=1959, ...)

@dataclass turns a class body into a schema โ€” no hand-written __init__, no repetitive assignment. The field declarations are the documentation.


06 โ€” The Whole Picture

More reasons Python endures

๐Ÿ”‹

Batteries Included

The standard library covers HTTP, JSON, CSV, dates, regex, compression, cryptography, and more โ€” before you install a single package.

๐Ÿ”ฌ

The Language of Science

NumPy, pandas, PyTorch, scikit-learn โ€” virtually all of modern data science and AI research is written in Python.

๐Ÿ”„

Iterators Everywhere

enumerate, zip, itertools โ€” Python's iteration protocol is composable. Generators let you express infinite sequences naturally.

๐Ÿงฉ

Dynamic but Typed

Type hints are optional and progressive. Add them where they help; leave them out where they don't. mypy and editors understand both.

๐Ÿ’ฌ

The REPL

Python ships with an interactive interpreter. Ideas become runnable in seconds. No compile step, no ceremony โ€” just exploration.

๐ŸŒ

Everywhere

Web backends, CLI tools, automation scripts, notebooks, embedded systems. Python is the duct tape of the modern software world โ€” and that's a compliment.