8 minutes read

Everyone knows how necessary good documentation is. When other programmers read your code, comments might be sufficient, but users won't see them. Users are going to read the documentation. Indeed, you've read many pieces of documentation, but have you ever written one? If you're thinking about long hours of painfully trying to formulate your thoughts – don't worry; it's much easier than that. The pydoc module was created for precisely that – generating documentation fast and straightforwardly. Let's learn how to use it!

Documenting functions

The pydoc module is part of the Python standard library, so you don't have to install it. There's no need to import it into your code; it can be used in the command line. Usually, your workflow is this: you write some code, save it to a file, run pydoc through the command line – and get the documentation. Easy, right? Let's go through this process step-by-step.

Pydoc isn't magic. It doesn't create documentation on its own; it just derives it from docstrings. You probably remember what a docstring is: a string, usually in triple quotes, that documents classes, modules, or functions. If there are no docstrings in your code, pydoc will use comments to generate documentation. So that's it, pydoc just takes docstrings or comments you've written and creates neat and easy-to-read documentation from it.

To see how it works, we have to write some code first. Let's start with a simple function:

def greet():
    """ Just print a greeting """
    print('Hi!')

Now, we'll save it as greet.py and open the command line. In the command line, we go to the directory where our file is stored and type pydoc -w greet (or python -m pydoc -w greet). Note that it's just greet, without the .py! -w means we want our documentation as an .html file. Documentation will be printed in the console if you don't use this argument. Here's what it may look like:

C:\Users\Username>pydoc -w greet
wrote greet.html

The wrote greet.html line means that the documentation has been created. Now, it's stored in the greet.html file in the same directory as greet.py. Let's have a look at this file:

Document file view

What do we have here? At the top, there's the filename (greet in our example) and the file path. Then, there's the Functions section, where all defined functions are listed: in our case, it's only one, greet(). Then you have the function's docstring. Simple, yet effective!

Now let's try something more advanced – documenting classes and methods.

Documenting classes

The process of documenting classes isn't much different from functions, but let's see how it's done. We'll define the Cat class to store a name and age of a cat. We'll also define the say_hi() method inside that class. Here's the code:

class Cat():
    """ Creates a Cat object """
    def __init__(self, name, age):
        """
        Initializes the object.

        Parameters:
        name - a string with the cat's name,
        age - an int, the cat's age
        """
        self.name = name
        self.age = age

    def say_hi(self):
        """ Prints a greeting with the cat's name """
        print('Hi, I am', self.name)

Pydoc imports modules to document them, so any code on the module level will be executed. For example, if our code has cat = Cat('Johny', 2) and cat.say_hi() lines, pydoc would execute them. We don't need that, so if there's something executable in your code, don't forget to put it under if __name__ == '__main__':

The documenting process is the same as before: save the module to cats.py, run pydoc -w cats in the command line and open the cats.html file that pydoc has created. Here's how it looks:

Pydoc generate document

Now, the Functions section is gone, which makes sense, as we haven't defined any functions in this example. But there we have the Classes section, where we can see our Cat class with its docstring, its methods, and their respective docstrings. There's also a section on data descriptors which is just a standard part of class documentation.

We had def say_hi() in our example, it was considered a class method, not a function, since it's inside the class. If we define a function outside the class, it summons the Functions section right after the Classes section.

Now we know how to document both classes and functions. Let's see how comments affect our documentation.

Adding comments

Until now, the documentation in our examples was generated from docstrings. However, pydoc can use comments as well. How it uses them depends on where they're placed and whether there are any docstrings.

Let's get back to our example with the greet() function. For this example, we'll remove the docstring and add several comments:

# a comment at the top

# a comment just before the function
def greet():
    # a comment inside the function
    print('Hi!')

# a comment at a random place in the code

Let's generate the documentation and see if any of the comments are there:

Comment add document

As you can see, only two of our comments made it to the documentation. The comment at the top of the file was placed at the top of the documentation. The comment before the function has taken the place of the docstring. Other comments have been ignored. So how does pydoc decide which comments to use? The rules are:

  • Ignore the comments inside functions and classes;

  • Ignore the comments at random places (like at the end of the code);

  • If a function or class has no docstring, use the comment just above this function or class;

  • If there's no docstring at the top of the module, use the comment at the top.

The rule of thumb is that pydoc prioritizes docstrings over comments.

Now, let's see what happens if we keep all the comments but also add some more docstrings:

# a comment at the top
""" A docstring at the top """

# a comment just before the function
def greet():
    """ A docstring inside the function """
    # a comment inside the function
    print('Hi!')

# a comment at a random place in the code

Greet.html looks like this:

Ignore comments pydoc

There are enough docstrings, so pydoc completely ignores the comments. It makes sense: while docstrings describe the behavior of modules and functions, comments can be just thoughts or ideas for fellow programmers. So, they are only used if there are no docstrings.

Now that you know all the basics; let's have a closer look at pydoc in the command line.

Command-line arguments

So far, we've seen the -w argument only; it means we want to write the documentation to an .html file. However, there are more arguments. Type pydoc -m in the command line to see all of them.

The arguments -n, -p, and -b are used to start an HTTP server to browse the documentation.

There's the -k argument (k for keyword). It lets you search through all the modules you have installed looking for a keyword. Note that only the first line of each module description will be browsed. For example, if you type pydoc -k statistics, you'd get a list of all modules with the word "statistics" in the first line of the description.

You can use pydoc not only for drawing documentation for your programs but also for accessing documentation of other modules or built-in classes. For example, if you type pydoc statistics, you'll get the statistics module documentaton printed in the console. If you add -w (pydoc -w statistics) you'll get an .html file with that documentation. It's equivalent to help(statistics), but if you want a prettier and more colorful representation, give pydoc a go!

Conclusion

In this topic, we've covered the basics of creating documentation with pydoc. Now you know how to document modules, functions, classes, and methods. Let's quickly go through the main points:

  • Documentation is generated from docstrings;

  • If there are no docstrings, the module will use comments;

  • Pydoc runs on a .py file in the command line;

  • Use pydoc filename to see the documentation in the console and pydoc -w filename to save it to an .html file.

If you want to learn more, check out the official documentation. Now it's time to practice!

Read more on this topic in Commenting the Right Way in Python Code on Hyperskill Blog.

67 learners liked this piece of theory. 3 didn't like it. What about you?
Report a typo