Documentation & Readability

Advanced · 18 min read · ▶ live playground · ✦ checkpoint

The best code explains most of itself. The next best thing is documentation, written guidance that helps a reader use, change, or trust the code without guessing.

Docstrings are the front label

A docstring is a string literal placed first inside a function, class, or module so Python can store it as that object's documentation. Think of a function as the recipe card from defining and calling functions; the docstring is the front label that tells you what the recipe makes before you read every step.

PEP 257 is Python's docstring convention, a shared habit for writing docstrings that tools and readers expect. Start with a short summary sentence. Use triple quotes. Say what the function does for the caller, not how every line works inside.

from inspect import getdoc
 
 
def award_message(player, score):
    """Return a short award message for one player."""
    if score >= 90:
        return f"{player}: badge earned"
    return f"{player}: keep practicing"
 
 
print(getdoc(award_message))
print(award_message("Mina", 94))

Return a short award message for one player.
Mina: badge earned

getdoc() reads the stored docstring in a clean form. Python's help() function uses the same idea: good docstrings make your code easier to explore from the REPL.

For tiny functions, one clear sentence is enough. For a function with arguments, return values, and edge cases, use a longer docstring.

Choose a docstring convention

A convention is a shared habit a community follows so everyone does not invent a new format in every file. Python gives you PEP 257 as the base. Larger teams often choose a named layout for details:

  • Google style is a docstring layout with labeled blocks like Args: and Returns:.
  • NumPy style is a docstring layout, named after the NumPy project, with sections like Parameters and Returns.

You do not need both in one project. Pick one and stay consistent.

def badge_line(player: str, score: int) -> str:
    """Return the badge line shown on a score card.
 
    Args:
        player: The player's display name.
        score: The player's numeric score.
 
    Returns:
        A short message for the score board.
    """
    if score >= 90:
        return f"{player}: badge earned"
    return f"{player}: keep practicing"
 
 
print(badge_line("Ravi", 72))

Ravi: keep practicing

The docstring does not repeat the if statement. It tells a reader what the function promises from the outside. That outside view matters because callers should not need to study every line before they can use a function.

Comments should earn their space

A comment is text after # that Python ignores but humans read. A useful comment is like a margin note beside a recipe card: it explains the reason behind a surprising choice.

def shipping_note(apples, distance_km):
    free_apples = apples
 
    # The market adds one thank-you apple for nearby delivery orders.
    if distance_km <= 3 and apples >= 5:
        free_apples = apples + 1
 
    return f"Pack {free_apples} apples"
 
 
print(shipping_note(5, 2))
print(shipping_note(5, 8))

Pack 6 apples
Pack 5 apples

The comment explains the business rule, a real-world rule the program must follow: nearby delivery orders get a bonus apple. Without that note, the number 3 and the extra apple look random.

Comments hurt when they repeat code or go stale. A stale comment is an old comment that no longer matches the code, which is worse than no comment because it lies with confidence.

Good comments usually explain one of these:

  • Why a rule exists.
  • Why a boring-looking line must stay.
  • Why a strange case is handled.
  • What source a number or rule came from.

Try it - read the public face first

Run this, then change the threshold from 90 to 85. Update the docstring only if the promise changes.

python — playgroundlive
⌘/Ctrl + Enter to run

Type hints document the shape

A type hint is an annotation that labels the kind of value a name expects, like a label on the function recipe card from type hints. It is not a locked door: Python stores the hint but does not enforce it by itself.

def score_summary(scores: list[int]) -> str:
    """Return the highest score and the number of scores."""
    high_score = max(scores)
    return f"{len(scores)} scores, best is {high_score}"
 
 
print(score_summary([82, 91, 77]))
print(score_summary.__annotations__)

3 scores, best is 91
{'scores': list[int], 'return': <class 'str'>}

The hint scores: list[int] tells the reader to pass a list of integers. The hint -> str says the function returns a string. The __annotations__ dictionary shows that Python keeps those labels as metadata, information stored about the function rather than behavior the function runs.

Type hints are living documentation because they sit beside the code they describe. If the function changes, the hint is right there waiting to be updated. In 14.3, you will meet tools that check those hints for you.

Generated docs start with readable code

A documentation generator is a tool that turns source text, docstrings, and examples into a browsable documentation site. Sphinx is a Python documentation generator often used for detailed Python package docs. MkDocs is a documentation generator that turns Markdown, plain text with lightweight symbols for headings and lists, into a site.

They do not make unclear writing clear. They organize the writing you already have.

Generated docs usually pull from three places:

  • Hand-written pages that explain goals, setup, and examples.
  • Docstrings from functions, classes, and modules.
  • Small code examples that show the expected use.

Use Sphinx when a project needs detailed Python reference pages pulled from docstrings. Use MkDocs when a project mostly needs friendly guide pages written in Markdown. Either way, the source still starts here: clear names, honest docstrings, useful comments, and type hints that match reality.

Checkpoint

Answer all three to mark this lesson complete

Readable documentation turns your code from a private thought into a tool another person can pick up. Next, you will add automated tools that keep style, linting, and type hints honest while the project grows.

+50 XP on completion