Python Docstrings and the doc Attribute

Python docstrings provide a built-in mechanism for documenting modules, classes, functions, and methods. When a string literal appears as the very first statement within an object's definition, the Python compiler binds it to that object's __doc__ attribute rather than executing it as standard code. This article explains how Python processes docstrings, how it exposes them via __doc__, how tools consume this metadata at runtime, and how docstrings differ from regular comments.

What is a Docstring?

A docstring (short for documentation string) is a string literal that occurs as the first statement in a module, function, class, or method definition. While single-line strings enclosed in single or double quotes can serve as docstrings, multi-line strings using triple quotes (""" or ''') are the standard convention defined in PEP 257.

Unlike comments, which are ignored by the Python interpreter, docstrings are retained as live metadata during program execution.

How Python Binds the __doc__ Attribute

When the Python compiler parses a code block (such as a module, function body, or class body), it inspects the first statement in the block's Abstract Syntax Tree (AST).

  1. Detection: If the first statement is an expression consisting solely of a string literal, the compiler designates it as a docstring.
  2. Assignment: During the creation of the underlying code object or namespace, Python automatically writes this string to the __doc__ attribute of the resulting object.
  3. Default Value: If no docstring is defined, the object is still created with a __doc__ attribute, but its value is initialized to None.
def calculate_area(width: float, height: float) -> float:
    """Calculate the area of a rectangle given width and height."""
    return width * height

print(calculate_area.__doc__)
# Output: Calculate the area of a rectangle given width and height.

Docstrings Across Different Scopes

The __doc__ attribute behaves consistently across modules, classes, and functions:

1. Functions and Methods

Inside functions, the docstring is attached directly to the function object.

def add(a, b):
    """Add two numbers and return the result."""
    return a + b

print(add.__doc__)

2. Classes

Inside classes, the docstring resides in the class namespace and is attached to the class object itself.

class DatabaseConnection:
    """Manages connections and transactions with the database."""
    pass

print(DatabaseConnection.__doc__)

3. Modules

For modules, a docstring placed at the top of the .py file is stored in the module's global __doc__ variable.

# In my_module.py
"""Utilities for network socket configuration."""

import sys
# ...

When imported, it can be accessed via my_module.__doc__.

Accessing Docstrings at Runtime

Besides direct attribute access via obj.__doc__, Python provides higher-level interfaces to read and display documentation:

import inspect

class Base:
    """Base class documentation."""
    pass

class Derived(Base):
    pass

print(Derived.__doc__)           # Output: None
print(inspect.getdoc(Derived))   # Output: Base class documentation.

Docstrings vs. Comments

Feature Docstring Comment (#)
Visibility Available at runtime via __doc__ Discarded during tokenization
Syntax String literal (""" or ''') Prefixed with #
Purpose Explains what an object does and how to use it Explains why non-obvious code was written
Tooling Consumed by IDEs, Sphinx, and help() Ignored by automated documentation tools

The Optimization Flag Caveat

Docstrings occupy memory because they are loaded into runtime memory as string objects. To reduce memory usage in resource-constrained environments, Python can be run with the -OO optimization flag:

python -OO script.py

When -OO is active, the bytecode compiler discards docstrings entirely, setting __doc__ to None for all functions, classes, and modules. For this reason, production code should never rely on the runtime existence of __doc__ for application logic or control flow.