PYTHON • FUNCTIONS AND PROGRAM STRUCTURE

Docstrings & Type Hints — Write docstrings and use type hints (intro) for readability

Learn to document your Python functions so that future-you and your teammates can understand your code at a glance.

Historical Context & Motivation

Have you ever opened up old code you wrote a few months ago and thought, "What was I trying to do here?" You are not alone. Since the earliest days of programming, developers have struggled with the challenge of making code understandable to other people — and to their future selves. Documentation is the practice of explaining what your code does, and Python has always treated readability as a first-class priority.

Python's creator, Guido van Rossum, famously said, "Code is read much more often than it is written." That philosophy led to two powerful features built right into the language: docstrings for human-readable documentation and type hints for signaling what kinds of data a function expects and returns.

1991
Python 0.9 Released
Guido van Rossum releases the first version of Python, emphasizing clean, readable syntax from the start.
2001
PEP 257 — Docstring Conventions
The Python community formalizes how docstrings should be written, establishing a standard that tools and developers can rely on.
2006
PEP 3107 — Function Annotations
Python 3.0 introduces the syntax for function annotations, laying the groundwork for type hints.
2014
PEP 484 — Type Hints
Python 3.5 officially adds a standard way to annotate function parameters and return types, making code easier to understand and check for errors.
2022+
Modern Python
Type hints and docstrings are now industry standard. Tools like mypy, VS Code, and PyCharm use them to catch bugs before you even run your code.

The central question these features address is simple: How can we write code that clearly communicates its purpose, inputs, and outputs — without forcing someone to read every line? Docstrings and type hints are Python's answer to that challenge.

Core Principles & Definitions

Before diving into code, let's define the two key ideas. A docstring is a special string placed at the very beginning of a function (or class, or module) that describes what it does. It is enclosed in triple quotes ("""...""") and is stored by Python so that other tools can access it. A type hint is an annotation you add to a function's parameters and return value to indicate the expected data types, like int, str, or float.

1

Docstrings Explain "What"

A docstring answers the question: What does this function do? It is written in plain English and lives inside the function definition.
2

Type Hints Explain "What Kind"

Type hints answer the question: What type of data goes in, and what type comes out? They appear in the function signature itself.
3

Both Are Optional (but Recommended)

Python will not raise an error if you skip them. However, professional codebases almost always use them because they dramatically reduce confusion and bugs.
4

Tools Read Them Automatically

Your code editor (like VS Code) and the built-in help() function can display docstrings and type hints as pop-up tooltips while you code.
✦ KEY TAKEAWAY
Think of a function like a kitchen appliance. The type hints are like the labels on the input and output slots — they tell you to put bread in and expect toast out. The docstring is like the instruction manual taped to the side — it explains what the appliance does, any special settings, and what could go wrong. Neither changes how the appliance works, but both make it much easier to use correctly.

Visual Explanation — Anatomy of a Documented Function

The diagram below shows a single Python function with every documentation feature labeled. Study how the type hints sit inside the function signature (the def line), while the docstring appears as the first line inside the function body.

The function signature contains parameter type hints (: float) and a return type hint (-> float). The docstring appears as the first line inside the function body, wrapped in triple quotes.

Notice how each piece of documentation occupies a specific location. The type hints are part of the def line itself — they sit right next to the parameter names and before the colon that ends the signature. The docstring, on the other hand, is a regular Python string that happens to be the very first statement inside the function. Python stores it in a special attribute called __doc__, which means you can retrieve it at any time by calling help(calculate_area) in the interactive console.

How Docstrings and Type Hints Work Under the Hood

Docstring Mechanics

When Python encounters a string literal as the first statement of a function, class, or module, it does not throw it away. Instead, it stores that string in the object's __doc__ attribute. This is not a comment — it is live data that programs, libraries, and editors can access. For example, if you type print(calculate_area.__doc__), Python will print the docstring you wrote.

💡 Comments vs. Docstrings
A comment (starting with #) is completely ignored by Python at runtime — it vanishes. A docstring is preserved and becomes part of the function object. Always use a docstring to describe a function's purpose, and use comments for inline notes about tricky logic.

Type Hint Mechanics

Type hints use a colon (:) after a parameter name and an arrow (->) before the final colon of the def line to annotate types. The general pattern is:

TYPE HINT SYNTAX
def func_name(param₁: Type₁, param₂: Type₂) -> ReturnType:
param₁, param₂ = parameter names; Type₁, Type₂ = expected input types (e.g., int, str); ReturnType = the type of the value the function returns.

Here is the crucial detail: Python does not enforce type hints at runtime. If your hint says x: int but you pass a string, Python will not stop you. Type hints are for humans and tools. External programs like mypy or your code editor can read the hints and warn you about mismatches before you run the program. Think of them as helpful road signs — they guide you, but they do not build physical barriers.

Common Built-in Types for Hints

The most common types you will use in high school Python projects.
TypeMeaningExample Value
intWhole number42
floatDecimal number3.14
strText string"hello"
boolTrue or FalseTrue
listOrdered collection[1, 2, 3]
NoneNo return value(used in return type)

Docstring Styles & Multi-Line Format

Docstrings come in two flavors: one-line and multi-line. A one-line docstring fits on a single line and is perfect for simple functions. A multi-line docstring is used when you need to describe parameters, return values, or special behavior in more detail. The most popular multi-line format for beginners is the Google style, which organizes information under headings like Args and Returns.

Use a one-line docstring for simple functions and a multi-line docstring when you need to describe parameters, return values, or edge cases. The Google-style format is the most beginner-friendly.

In the multi-line example, notice the structure: the first line is a brief summary, then a blank line, then the Args: section lists each parameter with an explanation, and the Returns: section describes what the function gives back. This consistent structure lets tools like Sphinx automatically generate beautiful HTML documentation for entire projects.

⚡ Pro Tip
In VS Code, you can type three double quotes """ right after the def line and press Enter. If you have the Python Docstring Generator extension installed, it will automatically scaffold a multi-line docstring template with all your parameters pre-filled!

Worked Example — Documenting a Function Step by Step

Let's walk through the process of taking an undocumented function and adding docstrings and type hints. We will use a function that converts a temperature from Fahrenheit to Celsius.

Adding Documentation to a Temperature Converter
1
Step 1 — Start with the bare functionHere is the original, undocumented function: def to_celsius(f): return (f - 32) * 5 / 9 This works, but a reader has to figure out what f means and what the function returns.
2
Step 2 — Add type hints to parameters and return valueWe know the input is a number (a float for decimal temperatures) and the output is also a float. We annotate both: def to_celsius(fahrenheit: float) -> float: Notice we also renamed f to fahrenheit for clarity — good naming works hand-in-hand with documentation.
Parameter hint: fahrenheit: float · Return hint: -> float
3
Step 3 — Write a one-line docstringSince this function is straightforward, a one-line docstring is sufficient. Place it as the first statement inside the function body: def to_celsius(fahrenheit: float) -> float: """Convert a temperature from Fahrenheit to Celsius.""" return (fahrenheit - 32) * 5 / 9
Docstring: """Convert a temperature from Fahrenheit to Celsius."""
4
Step 4 — Verify with help()In the Python console, call help(to_celsius). Python will display: Help on function to_celsius: to_celsius(fahrenheit: float) -> float Convert a temperature from Fahrenheit to Celsius. Both the type hints and the docstring appear automatically!
5
Step 5 — Expand to multi-line (optional upgrade)If we wanted to add more detail, we could expand to the Google style: def to_celsius(fahrenheit: float) -> float: """Convert a temperature from Fahrenheit to Celsius. Args: fahrenheit: Temperature in degrees Fahrenheit. Returns: Temperature converted to degrees Celsius. """ return (fahrenheit - 32) * 5 / 9
Fully documented function with type hints and a Google-style multi-line docstring.

Documented vs. Undocumented Code

To really appreciate the value of docstrings and type hints, let's compare two versions of the same function and see how each one reads to a new developer encountering the code for the first time.

Side-by-side comparison of undocumented vs. documented function approaches.
AspectUndocumented VersionDocumented Version
Function signaturedef calc(a, b):def calc_bmi(weight_kg: float, height_m: float) -> float:
Purpose clear?No — "calc" could mean anythingYes — the name and hints tell you it calculates BMI
Parameter meaningUnknown — what are a and b?Clear — weight in kg, height in meters
Return typeMust read the code to guessClearly a float
Editor supportMinimal autocompleteRich tooltips and error detection
Bug riskHigher — someone might pass stringsLower — the editor flags type mismatches
✦ KEY TAKEAWAY
Writing documentation is like labeling containers in a shared kitchen. Without labels, everyone has to open every container and sniff to figure out what is inside. With labels, people can find the flour in seconds. The few extra seconds you spend writing docstrings and type hints can save you and your teammates hours of confusion later.

Connection to Advanced Python Tooling

Docstrings and type hints are your entry point into a much larger ecosystem of professional Python tools. As you advance, these features become even more powerful. Here is a preview of where they lead.

How today's basics scale into professional development workflows.
What You Learn NowWhat It Unlocks Later
Basic type hints (int, str, float)Advanced types like list[int], dict[str, float], Optional[str], and generics
One-line docstringsAuto-generated documentation websites using Sphinx or MkDocs
Descriptive parameter namesAPI design where parameter names become part of public interfaces
Editor tooltips from type hintsStatic analysis with mypy that catches type errors across entire codebases
Google-style docstringsDoctest — embedding runnable test cases inside your docstrings

In college-level courses and industry jobs, you will encounter tools like mypy (a static type checker that reads your hints and flags bugs), Sphinx (which turns docstrings into full documentation websites), and Pydantic (which uses type hints to validate data at runtime). Every one of these tools builds on the exact skills you are learning today. Investing time in clean documentation now will pay dividends for years.

🔭 Looking Ahead
In Python 3.10+, you can use the | operator instead of Union for combined types. For example, def process(data: int | str) -> str: means the parameter can be either an int or a str. The syntax keeps getting simpler!

Practice Problems

PROBLEM 1 — CONCEPTUAL
Explain the difference between a comment (using #) and a docstring in Python. Why would you choose a docstring over a comment to describe a function?
PROBLEM 2 — BASIC CALCULATION
Add appropriate type hints to the following function signature. The function takes a student's name (text) and their score (a whole number), and returns a greeting message (text). def greet_student(name, score): return f"{name}, you scored {score} points!"
PROBLEM 3 — INTERMEDIATE
Write a complete, documented function called average that takes a list of floats and returns their average as a float. Include type hints for the parameter and return value, and write a multi-line Google-style docstring with Args and Returns sections.
PROBLEM 4 — APPLIED
You are building a gradebook application. Write a documented function called is_passing that takes a student's score (float) and an optional passing threshold (float, defaulting to 60.0), and returns True if the student passed and False otherwise. Include type hints and a Google-style docstring.
PROBLEM 5 — CRITICAL THINKING
A classmate argues: "Type hints are pointless because Python ignores them anyway — they don't actually prevent wrong types from being passed." Write a paragraph-length rebuttal explaining at least three concrete benefits of type hints, even though Python does not enforce them at runtime.

Lesson Summary

In this lesson, you learned two essential tools for writing readable Python code. Docstrings are triple-quoted strings placed as the first statement inside a function that describe its purpose, parameters, and return value. They are stored in the __doc__ attribute and can be accessed via help(). Type hints annotate the expected types of function parameters (using : type) and return values (using -> type). Although Python does not enforce type hints at runtime, they enable editor autocompletion, static type checking, and dramatically improved code readability.

You explored two docstring styles: one-line for simple functions and Google-style multi-line docstrings with Args and Returns sections for more complex functions. These skills form the foundation for professional documentation practices, auto-generated docs with Sphinx, and static analysis with tools like mypy. Remember: good documentation is a gift to your future self and to anyone who reads your code.

Varsity Tutors • Python • Docstrings & Type Hints