Introduction
The code you write today will be read by you or by your team after a few days or months or maybe after few years. If the code is not readable then you are going to spend your precious time figuring out what the module, class, function, or method is doing. Python docstrings are a great tool to make your code readable. Once docstrings are added to the code, you can easily access docstrings using help() and __doc__ attribute on the object and understand what the module, class, function, or method is doing.
This quote from Guido conveys the importance of commenting and documenting your code.
"Code is more often read than written."
Here is another one from Damian Conway on documentation.
"Documentation is a love letter that you write to your future self"
So how do you write readable code? There are a number of guidelines on writing readable code. However, in this article, we’ll focus on one of the methods called docstrings. Along the way, you will learn how docstrings are used with examples.
What are Docstrings
Docstrings or documentation strings are the string literals that appear in the first line of module, class, function, or methods definition. The docstrings are created by enclosing the documentation text within '''triple single-quotes'''
or """triple double-quotes"""
. Docstrings should explain what the module, class, function, or method does not how it does.
There are two types of docstrings: one-line docstrings and multi-line docstrings. Let’s understand both types with examples.
One-line Docstrings
As the name itself says, one-line docstrings fit in one line. Some of the characteristics of one-line docstrings you should keep in mind are –
- The docstring text should begin with a capital letter and end with a period.
- There should not be any blank line before or after the docstring.
- Docstring should not be repeating the function parameters. Instead, the docstring should follow
'Do <something> and return <something>'
format. For the below example, we could write docstring as"""Takes two numbers and returns sum."""
.
def func1(num1, num2):
return num1 + num2
Multi-line Docstrings
Unlike one-line docstrings, multi-line docstrings expand to multiple lines. Some of the characteristics of multi-line docstrings-
- The very first line of multi-line docstring is called the summary line and it is recommended that the summary line should fit in one line.
- The summary line is followed by a blank line.
- The blank line is followed by detailed documentation about the module, class, function, method.
- If docstring is for a function or method, then the docstring should contain a summary line and documentation for parameters, return values, exceptions, etc.
- If docstring is for a class, then the docstring should contain a summary line and the documentation for methods, instance variables, examples for method usage, etc.
- Similarly, if the docstring is for a module or package then it should contain documentation such as the list of classes, exceptions, functions.
Below is an example of multi-line docstring for a class. As you can see it contains summary line, followed by and blank like and followed by detailed documentation. Even without docstrings, you can still understand this class and methods. But when you are part of a bigger project, docstrings makes a lot sense.
class Rectange():
"""A class to represent a rectangle
Attributes:
height (float): height of rectangle
weight (float): weight of rectangle
Methods:
area: returns the area of rectangle
"""
def __init__(self, height, width):
"""Constructs all the necessary attributes for the rectangel object.
Parameters:
height (float): height of rectangle
weight (float): weight of rectangle
"""
self.height = height
self.width = width
def area(self):
"""This method returns area of the rectangle.
Parameters:
None
Returns:
float: returns area of the rectangle
"""
return self.height * self.width
How to access docstrings
The docstrings will become part of your code hence they will also be stored in the memory. You can access the docstring of module, class, function, or method using two methods as outlined below.
a) Using __doc__ attribute
Using the __doc__ attribute, you can get docstring for your module, function, class, or methods. In the below example, you are able to access the docstring of function by using the __doc__ attribute. For the above Rectangle class example, let’s see how to get docstrings using __doc__ attribute.
r1 = Rectange(10,20)
print(r1.__doc__)
Output:
A class to represent a rectangle
Attributes:
height (float): height of rectangle
weight (float): weight of rectangle
Methods:
area: returns the area of rectangle
b) Using built-in help() function
Another way to access docstrings is using Python’s built-in help()
function as you can see from the below example. The built-in help() function gave very detailed documentation including docstrings for methods.
r1 = Rectange(10,20)
print(help(Rectange))
Output:
Help on class Rectange in module __main__:
class Rectange(builtins.object)
| Rectange(height, width)
|
| A class to represent a rectangle
|
| Attributes:
| height (float): height of rectangle
| weight (float): weight of rectangle
|
| Methods:
| area: returns the area of rectangle
|
| Methods defined here:
|
| __init__(self, height, width)
| Constructs all the necessary attributes for the rectangel object.
|
| Parameters:
| height (float): height of rectangle
| weight (float): weight of rectangle
|
| area(self)
| This method returns area of the rectangle.
|
| Parameters:
| None
|
| Returns:
| float: returns area of the rectangle
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
None
Since both __doc__ attribute and help() function can be used on any object, the below code also gives docstring accordingly. You can try these out.
print(r1.area.__doc__)
This method returns area of the rectangle.
Parameters:
None
Returns:
float: returns area of the rectangle
print(help(r1.area))
Help on method area in module __main__:
area() method of __main__.Rectange instance
This method returns area of the rectangle.
Parameters:
None
Returns:
float: returns area of the rectangle
Docstrings Vs. Comments
Comments start with a #
at the beginning of the line. As you are already aware comments are ignored by the Python interpreter. As a result, they will not be stored in the memory and you won’t be able to access them as you did with docstrings by using __doc__
attribute or help()
function.
Though docstrings and comments look similar both are fundamentally different. The docstrings explain the overall functionality of the module, class, function, or methods while comments explain what a particular piece of code does. Sometimes part of the code is commented for testing some conditions and also used for mentioning TODO tasks. Nevertheless, comments are also an important part of the code and help in making your code more readable.
In general, comments are for developers and docstrings are for users.
Docstring formats
There are different docstring formats that you can follow for writing docstrings. Don’t get overwhelmed by the different formats out there. The key is to follow one format consistently for the entire project for better results.
I personally like both Google docstring format and Numpy/Scipy docstring format. In fact, the docstring function examples you saw above follow the Google docstring format. Refer to the hyperlinks given above for docstring examples of modules, classes, methods, scripts, etc.
Additionally, there are tools that such as Python’s built-in tool Pydoc that helps in generating the documentation automatically from the Python module. We will cover this in more detail in a future article.
Conclusion
In this article, you have understood the importance of writing readable code in Python using docstrings. Since there are many docstring formats available, you can select the one you are comfortable with and use it in your project consistently. If you are working on bigger projects the tools like Pydoc come in handy in generating documentation for the project.