Best Practices for Python Docstrings

In this Tutorial we will discuss the best practices and most recommended formats to write docstrings in Python.

Although docstrings can be written in any style as long as their purpose is being fulfilled, over time several popular ways of writing docstrings have cropped up. In this tutorial we will be discussing three such formats which are widely used by the Python community and in official libraries and companies.


Best Practices when writing Docstrings

Before we discuss the various formats, let’s take a look at the basic qualities and best practices that should be observed while writing docstrings.

  1. Short, concise and easily readable
  2. Every Class/Function/Module should have a description (generally 1-3 lines)
  3. Should contain argument lists for every function/method, where each argument is listed along with it’s type and a short description.
  4. Every Class should have an attribute list, where all public attributes (variables) are listed with their datatype and description.
  5. The Docstring for a module should list the Classes and Functions exported by the module, with a short one line description. (The proper descriptions should be within the docstrings for each Class/Function)
  6. A Class docstring may include a list of all the method signatures.
  7. A Function should specify in its docstring any possible exceptions that it might throw during it’s execution.

Listed above are 7 practices that are commonly found across the all types of docstrings. You do not need to apply all 7 at once, rather it depends on your situation.

If you are writing code for yourself (private use only) you need not go into so much detail, and simply following the basic points will be good enough (point 1 – 4).

If you are publishing a library for a large community or a large organization, then it is recommended to follow all 7 points (where possible).


Now let’s a discuss few popular and widely used accept styles. Though they may differ a bit in how they look, they all obey most, if not all of the previously mentioned “Best Practices” for docstrings.


Google Doc

First up is the Google-styled Docstrings. These are a style introduced and used by Google which is also extensively used in the community. It’s simple and easy to understand, so it’s good format to use.

Below is a simple example using Google Docstrings.

class Calculator:
    """
    Contains various functions to perform common 
    mathematical operations between two numbers
    
    Attributes:
        prevSum (int): Stores value of previous operation
    """

    def __init__(self):
        """
        Initializes class attributes
        
        Args:
            No arguments
        """

        self.prevSum = 0

    def add(num1, num2):
        """
        Calculate sum of two numbers
        
        Args:
            num1 (int): First Value
            num2 (int): Second Value
            
        Returns:
            Sum of num1 and num2
        """

        return num1 + num2

If you compare the above Code to the 7 rules mentioned earlier, you can see how it follows them all. Some rules don’t need to be followed, for example we are not creating any modules here. So no need for a module docstring. Neither will any exceptions be raised.

The main point here is the layout and headings used, which is what makes it different from the other styles. For more information and examples on Google docstrings, refer to this tutorial.


Numpy doc

Numpy Docstrings are very popular amongst the Scientific community in Python, so if you use the scientific libraries in Python alot you will encounter this type of docstring.

Now let’s take a look at the Numpy Docstring equivalent to the Calculator Code.

class Calculator:
    """
    Contains various functions to perform common 
    mathematical operations between two numbers
    
    Attributes
    ----------
    prevSum : int
       Stores value of previous operation
    """

    def __init__(self):
        """
        Initializes class attributes
        
        Parameters
        ----------
            No arguments
        """

        self.prevSum = 0

    def add(num1, num2):
        """
        Calculate sum of two numbers
        
        Parameters
        ----------
        num1 : int
            First Value
        num2 : int
            Second Value
            
        Returns
        -------
        Sum of num1 and num2
        """

        return num1 + num2

As you can see, it’s requires a few extra lines compared to Google Doc, but also looks very neat.

For more examples and other cases using Numpy Docs, follow the link.


Sphinx

Lastly we have the Sphinx Documentation. This kind of documentation is a bit harder to understand, so you may be confused as to why we use it.

The Sphinx docstring has it’s own proper syntax, which is actually used to auto generate documentation. Although it’s harder for us to understand, writing it in this way is nessacery for the auto-generation to work smoothly.

The auto-generation of documentation with Sphinx can be done using the autodoc extension.

class Calculator:
    """
    Contains various functions to perform common 
    mathematical operations between two numbers
    
    :var prevSum: Stores value of previous operation
    :vartype prevSum: int
    """

    def __init__(self):
        """Initializes class attributes"""

        self.prevSum = 0

    def add(num1, num2):
        """
        Calculate sum of two numbers
        
        :param num1: First Value
        :type num1: int
        :param num2: Second Value
        :type num2: int
                 
        :return: Sum of num1 and num2
        :rtype: int
        """

        return num1 + num2

This marks the end of the Best Practices for Python Docstrings Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments