How will someone know what a function does without opening its implementation? Give it a docstring: a string that documents how to use a function, method, class, or module. For a function, place it immediately below the function header, conventionally inside matched triple quotes. Users can inspect it with `help()` or the function’s `__doc__` attribute. section 6.5 section 6.5.1
Listing 6.13 Getting the docstring by using help
>>> help(isinstance) Help on built-in function isinstance in module builtins: isinstance(obj, class_or_tuple, /) Return whether an object is an instance of a class or of a subclass thereof. A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B) or ...`` etc.
The `help(isinstance)` listing shows a docstring answering a practical usage question directly in the Python console. section 6.5
For a public function, document the details a caller needs:
- Start with a concise summary of the function’s action. A simple, self-explanatory function may need only this one line. section 6.5.2
- Describe each parameter by its exact name, expected type, and purpose. Mention a default when present, particularly if its choice needs explanation. section 6.5.3
- State the return value and any exceptions callers may need to avoid or handle. section 6.5.1 section 6.5.4
Document a division function
A reST-style docstring can keep those details together: ```python def quotient(dividend, divisor, taking_int=False): """Divide two numbers, optionally returning an integer. :param dividend: int | float, number to divide :param divisor: int | float, number to divide by :param taking_int: bool, return the integer part; default False :return: float | int, the quotient :raises: ZeroDivisionError, if divisor is zero """ if divisor == 0: raise ZeroDivisionError("division by zero") result = dividend / divisor return int(result) if taking_int else result ``` The exception entry matters even when Python would raise the error during division without an explicit check. section 6.5.3 section 6.5.4
Google and reST are both used for docstrings; choose a style and keep it consistent across a project or team. Sensible function and parameter names should make the code understandable on their own, with the docstring supplying details when needed. section 6.5.1 section 6.5.3 section 6.5.5
A decorator can replace a function’s visible docstring with its inner function’s docstring—or leave `__doc__` as `None`. Apply `functools.wraps` to the inner function to preserve the decorated function’s docstring and name. section 7.3.3
Listing 7.9 Wrapping the decorated function
import functools
def logging_time_wraps(func):
@functools.wraps(func)
def logger(*args, **kwargs):
"""Log the time"""
print(f"--- {func.__name__} starts")
start_t = time.time()
value_returned = func(*args, **kwargs)
end_t = time.time()
print(f"*** {func.__name__} ends; used time:
{end_t - start_t:.2f} s")
return value_returned
return logger
@logging_time_wraps
def example_wraps():
"""Example function"""
pass
print(example_wraps.__doc__, example_wraps.__name__, sep="; ")
# output: Example function; example_wraps
The listing contrasts an inner function’s own docstring with the original docstring retained through `functools.wraps`. section 7.3.3





