I’ve been asked a few times recently about how to write good docstrings in Python so I thought I’d put a few notes up for everyone to refer back to later.
What is it?
There’s no need to re-invent the wheel here so the best thing is to read the python definition on what-is-a-docstring.
But, having said that I will highlight the purpose of a docstring for those of you, like me, who are too lazy to bother reading those pages - a docstring is a piece of text that occurs as the first line(s) in a python function, class, or module. This text becomes the
__doc__ special attribute of that object and is used to help users know what the thing you wrote is, does, and needs. Without a docstring your work is pretty useless and almost completely un-reusable and un-sharable. For me, docstrings are all about the re-usability and sharability.
Every function you write needs a docstring - in fact I’d say this is the most important thing you can do when writing a function (aside from testing, but you’re already doing that…right?).
A good docstring contains three elements:
- a one line description of the purpose.
- a clear description of the inputs and outputs to the function.
typeeach input and output will be.
Here is how to write a good docstring for a function:
def add_binary(a, b): ''' Returns the sum of two decimal numbers in binary digits. Args: a (int): A decimal integer b (int): Another decimal integer Returns: binary_sum (str): Binary string of the sum of a and b ''' binary_sum = bin(a+b)[2:] return binary_sum
The docstring has now become the objects
__doc__ attribute and can now be used by users to get help on the use of the function:
Returns the sum of two decimal numbers in binary digits. Args: a (int): A decimal integer b (int): Another decimal integer Returns: binary_sum (str): Binary string of the sum of a and b
Most people are good at putting docstrings in their function but people often forget to put them in the classes they write. The docstring for a class is very similar to the function docstring but it has two extra elements:
- a description of the basic behavior of the class.
- a list of the public methods available to the user.
Here is an example of a class docstring:
class Person: """ A class to represent a person. some blah about why/what it does. Args: name (str): The first name of the person surname (str): The family name of the person age (int): The age of the person Methods: info(additional=""): Prints the person's name and age. """ def __init__(self, name, surname, age): """ Constructs all the necessary attributes for the person object. Args: name (str): The first name of the person surname (str): The family name of the person age (int): The age of the person """ self.name = name self.surname = surname self.age = age ...
As per the function docstring this text is also assigned to the
__docstring__ attribute for the class.
we can see that by:
A class to represent a person. some blah about why/what it does. Args: name (str): The first name of the person surname (str): The family name of the person age (int): The age of the person Methods: info(additional=""): Prints the person's name and age.
If people are slack with class docstring then they are completely hopeless when it comes to docstrings in Modules. Module docstrings are much like a Class docstring except that it also includes descriptions of the classes available in the module. This is best way to understand this is with an example. Here we will look at the
import pickle print(pickle.__doc__)
Create portable serialized representations of Python objects. See module cPickle for a (much) faster implementation. See module copy_reg for a mechanism for registering custom picklers. See module pickletools source for extensive comments. Classes: Pickler Unpickler Functions: dump(object, file) dumps(object) -> string load(file) -> object loads(string) -> object Misc variables: __version__ format_version compatible_formats
Here, we can see the docstring that is written at the beginning of the
pickle.py module file which has been assigned to the
__doc__ attribute for the module and can be be accessed as its docstring.
There is a help() function in python that leverages all of these docstrings and aggregates them into a nice little manual for the user to explore your code. Again, Pickle is a good example:
import pickle help(pickle)
I won’t paste the output here as it’s too long… go run it yourself and see what happens…
If you need inspiration check out pep 257 – Docstring Conventions or go hunting around in your favourite python module.