Python Docstring Formats (Styles) and Examples

Posted: | Tags: Python

In Python, strings written at the beginning of definitions such as functions and classes are treated as docstrings (documentation strings).

IDEs or editors may offer keyboard shortcuts to display docstrings for easy reference. Moreover, some of them use information from the docstrings for static analysis and provide warnings accordingly.

Display docstrings

To include a docstring in a function, write the string as shown below. Docstring formats will be discussed later.

def my_func():
    """docstring-test
    line1
    line2
    line3
    """
source: docstring.py

__doc__ attribute

The docstring is stored as a string in the __doc__ attribute and can be printed using the print() function.

print(my_func.__doc__)
# docstring-test
#     line1
#     line2
#     line3
#     

print(type(my_func.__doc__))
# <class 'str'>
source: docstring.py

Built-in help() function

In interactive environments such as Jupyter Notebook or the Python interpreter launched via python or python3 command, the built-in help() function displays the docstring through an interactive help system.

help(my_func)
# Help on function my_func in module __main__:
# 
# my_func()
#     docstring-test
#     line1
#     line2
#     line3
# 
source: docstring.py

The interactive help system in the terminal can be exited by pressing q.

Displaying docstrings in IDEs and Editors

Some IDEs and editors allow viewing docstrings through shortcut keys.

Jupyter Notebook

In Jupyter Notebook, placing the caret over a target function and pressing shift + tab displays the docstring in a tooltip. Holding down shift and repeatedly pressing tab changes the display style.

Visual Studio Code (VSCode)

In Visual Studio Code (VSCode) with the Python extension installed, hovering the cursor over the target function shows the docstring in a tooltip. The docstring can also be displayed by placing the caret over the function and using the shortcut command + k, command + i (or control + k, control + i).

Basic writing of docstrings

This section explains the basic way to write docstrings in functions and classes. Docstring formats for arguments and return values will be introduced later.

At the beginning of a definition, enclose a string within triple quotes (''' or """).

def my_func():
    """docstring-test
    line1
    line2
    line3
    """
source: docstring.py

You can use single (') or double (") quotes for docstrings, but even for single-line docstrings, triple quotes are often used by convention.

def my_func2():
    'docstring-test'

print(my_func2.__doc__)
# docstring-test
source: docstring.py

A docstring will not be recognized unless it's at the beginning of the definition.

def my_func_error():
    a = 100
    """docstring-test
    line1
    line2
    line3
    """

print(my_func_error.__doc__)
# None
source: docstring.py

The same rules apply for classes. Place a string at the beginning of the class definition.

class MyClass:
    """docstring-test
    line1
    line2
    line3
    """

print(MyClass.__doc__)
# docstring-test
#     line1
#     line2
#     line3
#     
source: docstring.py

Docstring formats and example

Docstrings often contain descriptions and types of function arguments and return values. However, there is no standardized format for this.

Here are three popular styles:

  • reStructuredText (reST) style
  • NumPy style
  • Google style

If your organization or project does not have specific guidelines, you may find it helpful to refer to these styles.

These styles also have the advantage of compatibility with documentation generators and IDE/editor assistance features. For example, reStructuredText, NumPy, and Google styles can all be converted into HTML documentation using Sphinx.

Some IDEs and editors provide type hints and error checking for these styles. For example, PyCharm, an integrated development environment for Python, supports all three styles.

reStructuredText (reST) style

def func_rest(param1, param2):
    """Summary line.

    :param param1: Description of param1
    :type param1: int
    :param param2: Description of param2
    :type param2: str
    :returns: Description of return value
    :rtype: bool
    """
    return True
source: docstring.py

For example, the reST style is used in Requests. The following is an actual code example.

def resolve_proxies(request, proxies, trust_env=True):
    """This method takes proxy information from a request and configuration
    input to resolve a mapping of target proxies. This will consider settings
    such a NO_PROXY to strip proxy configurations.

    :param request: Request or PreparedRequest
    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
    :param trust_env: Boolean declaring whether to trust environment configs

    :rtype: dict
    """
source: utils.py

NumPy style

The docstring style that supports numpydoc, a Sphinx extension for NumPy documentation:

def func_numpy(param1, param2):
    """Summary line.

    Extended description of function.

    Parameters
    ----------
    param1 : int
        Description of param1
    param2 : str
        Description of param2

    Returns
    -------
    bool
        Description of return value
    """
    return True
source: docstring.py

In addition to being used in NumPy, this style is also used in pandas.

The following is an actual code example.

def get_compressed_ids(
    labels, sizes: Shape
) -> tuple[npt.NDArray[np.intp], npt.NDArray[np.int64]]:
    """
    Group_index is offsets into cartesian product of all possible labels. This
    space can be huge, so this function compresses it, by computing offsets
    (comp_ids) into the list of unique labels (obs_group_ids).

    Parameters
    ----------
    labels : list of label arrays
    sizes : tuple[int] of size of the levels

    Returns
    -------
    np.ndarray[np.intp]
        comp_ids
    np.ndarray[np.int64]
        obs_group_ids
    """
source: sorting.py

Google style

The docstring style as defined in Google's Python style guide:

def func_google(param1, param2):
    """Summary line.

    Extended description of function.

    Args:
        param1 (int): Description of param1
        param2 (str): Description of param2

    Returns:
        bool: Description of return value

    """
    return True
source: docstring.py

The following is an actual code example in TensorFlow.

def size_internal(input, name=None, optimize=True, out_type=dtypes.int32):
  # pylint: disable=redefined-builtin,protected-access
  """Returns the size of a tensor.

  Args:
    input: A `Tensor` or `SparseTensor`.
    name: A name for the operation (optional).
    optimize: if true, encode the size as a constant when possible.
    out_type: (Optional) The specified non-quantized numeric output type of the
      operation. Defaults to `tf.int32`.

  Returns:
    A `Tensor` of type `out_type`. Defaults to `tf.int32`.
  """
source: array_ops.py

Function annotations

Starting from Python 3.0, you can annotate function arguments and return values.

def func_annotations_type(x: str, y: int) -> str:
    return x * y

Function annotations are merely annotations. They are not checked during runtime, but some IDEs and editors use them for various purposes.

Function annotations and docstrings are not mutually exclusive. It's common to use both. Types are often described using function annotations, while more detailed explanations are usually provided in the docstrings.

Related Categories

Related Articles