Documenting Python Code: A Complete Guide (original) (raw)

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Documenting Code in Python

Welcome to your complete guide to documenting Python code. Whether you’re documenting a small script or a large project, whether you’re a beginner or a seasoned Pythonista, this guide will cover everything you need to know.

We’ve broken up this tutorial into four major sections:

  1. Why Documenting Your Code Is So Important: An introduction to documentation and its importance
  2. Commenting vs Documenting Code: An overview of the major differences between commenting and documenting, as well as the appropriate times and ways to use commenting
  3. Documenting Your Python Code Base Using Docstrings: A deep dive into docstrings for classes, class methods, functions, modules, packages, and scripts, as well as what should be found within each one
  4. Documenting Your Python Projects: The necessary elements and what they should contain for your Python projects

Feel free to read through this tutorial from beginning to end or jump to a section you’re interested in. It was designed to work both ways.

Take the Quiz: Test your knowledge with our interactive “Documenting Python Code: A Complete Guide” quiz. You’ll receive a score upon completion to help you track your learning progress:


Documenting Python Code Guide

Interactive Quiz

Documenting Python Code: A Complete Guide

In this quiz, you'll test your understanding of documenting Python code. With this knowledge, you'll be able to effectively document your Python scripts and projects, making them more understandable and maintainable.

Why Documenting Your Code Is So Important

Hopefully, if you’re reading this tutorial, you already know the importance of documenting your code. But if not, then let me quote something Guido mentioned to me at a recent PyCon:

“Code is more often read than written.”

Guido van Rossum

When you write code, you write it for two primary audiences: your users and your developers (including yourself). Both audiences are equally important. If you’re like me, you’ve probably opened up old codebases and wondered to yourself, “What in the world was I thinking?” If you’re having a problem reading your own code, imagine what your users or other developers are experiencing when they’re trying to use or contribute to your code.

Conversely, I’m sure you’ve run into a situation where you wanted to do something in Python and found what looks like a great library that can get the job done. However, when you start using the library, you look for examples, write-ups, or even official documentation on how to do something specific and can’t immediately find the solution.

After searching, you come to realize that the documentation is lacking or even worse, missing entirely. This is a frustrating feeling that deters you from using the library, no matter how great or efficient the code is. Daniele Procida summarized this situation best:

“It doesn’t matter how good your software is, because **if the documentation is not good enough, people will not use it.**“

Daniele Procida

In this guide, you’ll learn from the ground up how to properly document your Python code from the smallest of scripts to the largest of Python projects to help prevent your users from ever feeling too frustrated to use or contribute to your project.

Before we can go into how to document your Python code, we need to distinguish documenting from commenting.

In general, commenting is describing your code to/for developers. The intended main audience is the maintainers and developers of the Python code. In conjunction with well-written code, comments help to guide the reader to better understand your code and its purpose and design:

“Code tells you how; Comments tell you why.”

Jeff Atwood (aka Coding Horror)

Documenting code is describing its use and functionality to your users. While it may be helpful in the development process, the main intended audience is the users. The following section describes how and when to comment your code.

Comments are created in Python using the pound sign (#) and should be brief statements no longer than a few sentences. Here’s a simple example:

According to PEP 8, comments should have a maximum length of 72 characters. This is true even if your project changes the max line length to be greater than the recommended 80 characters. If a comment is going to be greater than the comment char limit, using multiple lines for the comment is appropriate:

Commenting your code serves multiple purposes, including:

Comments to your code should be kept brief and focused. Avoid using long comments when possible. Additionally, you should use the following four essential rules as suggested by Jeff Atwood:

  1. Keep comments as close to the code being described as possible. Comments that aren’t near their describing code are frustrating to the reader and easily missed when updates are made.
  2. Don’t use complex formatting (such as tables or ASCII figures). Complex formatting leads to distracting content and can be difficult to maintain over time.
  3. Don’t include redundant information. Assume the reader of the code has a basic understanding of programming principles and language syntax.
  4. Design your code to comment itself. The easiest way to understand code is by reading it. When you design your code using clear, easy-to-understand concepts, the reader will be able to quickly conceptualize your intent.

Remember that comments are designed for the reader, including yourself, to help guide them in understanding the purpose and design of the software.

Type hinting was added to Python 3.5 and is an additional form to help the readers of your code. In fact, it takes Jeff’s fourth suggestion from above to the next level. It allows the developer to design and explain portions of their code without commenting. Here’s a quick example:

From examining the type hinting, you can immediately tell that the function expects the input name to be of a type str, or string. You can also tell that the expected output of the function will be of a type str, or string, as well. While type hinting helps reduce comments, take into consideration that doing so may also make extra work when you are creating or updating your project documentation.

You can learn more about type hinting and type checking from this video created by Dan Bader.

Documenting Your Python Code Base Using Docstrings

Now that we’ve learned about commenting, let’s take a deep dive into documenting a Python code base. In this section, you’ll learn about docstrings and how to use them for documentation. This section is further divided into the following sub-sections:

  1. Docstrings Background: A background on how docstrings work internally within Python
  2. Docstring Types: The various docstring “types” (function, class, class method, module, package, and script)
  3. Docstring Formats: The different docstring “formats” (Google, NumPy/SciPy, reStructuredText, and Epytext)

Docstrings Background

Documenting your Python code is all centered on docstrings. These are built-in strings that, when configured correctly, can help your users and yourself with your project’s documentation. Along with docstrings, Python also has the built-in function help() that prints out the objects docstring to the console. Here’s a quick example:

How is this output generated? Since everything in Python is an object, you can examine the directory of the object using the dir() command. Let’s do that and see what find:

Within that directory output, there’s an interesting property, __doc__. If you examine that property, you’ll discover this:

Voilà! You’ve found where docstrings are stored within the object. This means that you can directly manipulate that property. However, there are restrictions for builtins:

Any other custom object can be manipulated:

Python has one more feature that simplifies docstring creation. Instead of directly manipulating the __doc__ property, the strategic placement of the string literal directly below the object will automatically set the __doc__ value. Here’s what happens with the same example as above:

There you go! Now you understand the background of docstrings. Now it’s time to learn about the different types of docstrings and what information they should contain.

Docstring Types

Docstring conventions are described within PEP 257. Their purpose is to provide your users with a brief overview of the object. They should be kept concise enough to be easy to maintain but still be elaborate enough for new users to understand their purpose and how to use the documented object.

In all cases, the docstrings should use the triple-double quote (""") string format. This should be done whether the docstring is multi-lined or not. At a bare minimum, a docstring should be a quick summary of whatever is it you’re describing and should be contained within a single line:

Multi-lined docstrings are used to further elaborate on the object beyond the summary. All multi-lined docstrings have the following parts:

All docstrings should have the same max character length as comments (72 characters). Docstrings can be further broken up into three major categories:

Class Docstrings

Class Docstrings are created for the class itself, as well as any class methods. The docstrings are placed immediately following the class or class method indented by one level:

Class docstrings should contain the following information:

The class constructor parameters should be documented within the __init__ class method docstring. Individual methods should be documented using their individual docstrings. Class method docstrings should contain the following:

Let’s take a simple example of a data class that represents an Animal. This class will contain a few class properties, instance properties, a __init__, and a single instance method:

Package and Module Docstrings

Package docstrings should be placed at the top of the package’s __init__.py file. This docstring should list the modules and sub-packages that are exported by the package.

Module docstrings are similar to class docstrings. Instead of classes and class methods being documented, it’s now the module and any functions found within. Module docstrings are placed at the top of the file even before any imports. Module docstrings should include the following:

The docstring for a module function should include the same items as a class method:

Script Docstrings

Scripts are considered to be single file executables run from the console. Docstrings for scripts are placed at the top of the file and should be documented well enough for users to be able to have a sufficient understanding of how to use the script. It should be usable for its “usage” message, when the user incorrectly passes in a parameter or uses the -h option.

If you use argparse, then you can omit parameter-specific documentation, assuming it’s correctly been documented within the help parameter of the argparser.parser.add_argument function. It is recommended to use the __doc__ for the description parameter within argparse.ArgumentParser’s constructor. Check out our tutorial on Command-Line Parsing Libraries for more details on how to use argparse and other common command line parsers.

Finally, any custom or third-party imports should be listed within the docstrings to allow users to know which packages may be required for running the script. Here’s an example of a script that is used to simply print out the column headers of a spreadsheet:

Docstring Formats

You may have noticed that, throughout the examples given in this tutorial, there has been specific formatting with common elements: Arguments, Returns, and Attributes. There are specific docstrings formats that can be used to help docstring parsers and users have a familiar and known format. The formatting used within the examples in this tutorial are NumPy/SciPy-style docstrings. Some of the most common formats are the following:

Formatting Type Description Supported by Sphynx Formal Specification
Google docstrings Google’s recommended form of documentation Yes No
reStructuredText Official Python documentation standard; Not beginner friendly but feature rich Yes Yes
NumPy/SciPy docstrings NumPy’s combination of reStructuredText and Google Docstrings Yes Yes
Epytext A Python adaptation of Epydoc; Great for Java developers Not officially Yes

The selection of the docstring format is up to you, but you should stick with the same format throughout your document/project. The following are examples of each type to give you an idea of how each documentation format looks.

Google Docstrings Example

reStructuredText Example

NumPy/SciPy Docstrings Example

Epytext Example

Documenting Your Python Projects

Python projects come in all sorts of shapes, sizes, and purposes. The way you document your project should suit your specific situation. Keep in mind who the users of your project are going to be and adapt to their needs. Depending on the project type, certain aspects of documentation are recommended. The general layout of the project and its documentation should be as follows:

project_root/ │ ├── project/ # Project source code ├── docs/ ├── README ├── HOW_TO_CONTRIBUTE ├── CODE_OF_CONDUCT ├── examples.py

Projects can be generally subdivided into three major types: Private, Shared, and Public/Open Source.

Private Projects

Private projects are projects intended for personal use only and generally aren’t shared with other users or developers. Documentation can be pretty light on these types of projects. There are some recommended parts to add as needed:

Remember, even though private projects are intended for you personally, you are also considered a user. Think about anything that may be confusing to you down the road and make sure to capture those in either comments, docstrings, or the readme.

Shared Projects

Shared projects are projects in which you collaborate with a few other people in the development and/or use of the project. The “customer” or user of the project continues to be yourself and those limited few that use the project as well.

Documentation should be a little more rigorous than it needs to be for a private project, mainly to help onboard new members to the project or alert contributors/users of new changes to the project. Some of the recommended parts to add to the project are the following:

Public and Open Source Projects

Public and Open Source projects are projects that are intended to be shared with a large group of users and can involve large development teams. These projects should place as high of a priority on project documentation as the actual development of the project itself. Some of the recommended parts to add to the project are the following:

The Four Main Sections of the docs Folder

Daniele Procida gave a wonderful PyCon 2017 talk and subsequent blog post about documenting Python projects. He mentions that all projects should have the following four major sections to help you focus your work:

The following table shows how all of these sections relates to each other as well as their overall purpose:

Most Useful When We’re Studying Most Useful When We’re Coding
Practical Step Tutorials How-To Guides
Theoretical Knowledge Explanation Reference

In the end, you want to make sure that your users have access to the answers to any questions they may have. By organizing your project in this manner, you’ll be able to answer those questions easily and in a format they’ll be able to navigate quickly.

Documentation Tools and Resources

Documenting your code, especially large projects, can be daunting. Thankfully there are some tools out and references to get you started:

Along with these tools, there are some additional tutorials, videos, and articles that can be useful when you are documenting your project:

  1. Carol Willing - Practical Sphinx - PyCon 2018
  2. Daniele Procida - Documentation-driven development - Lessons from the Django Project - PyCon 2016
  3. Eric Holscher - Documenting your project with Sphinx & Read the Docs - PyCon 2016
  4. Titus Brown, Luiz Irber - Creating, building, testing, and documenting a Python project: a hands-on HOWTO - PyCon 2016
  5. reStructuredText Official Documentation
  6. Sphinx’s reStructuredText Primer
  7. Documenting Python Projects With Sphinx and Read the Docs
  8. Document Your Python Code and Projects With ChatGPT

Sometimes, the best way to learn is to mimic others. Here are some great examples of projects that use documentation well:

Where Do I Start?

The documentation of projects have a simple progression:

  1. No Documentation
  2. Some Documentation
  3. Complete Documentation
  4. Good Documentation
  5. Great Documentation

If you’re at a loss about where to go next with your documentation, look at where your project is now in relation to the progression above. Do you have any documentation? If not, then start there. If you have some documentation but are missing some of the key project files, get started by adding those.

In the end, don’t get discouraged or overwhelmed by the amount of work required for documenting code. Once you get started documenting your code, it becomes easier to keep going. Feel free to comment if you have questions or reach out to the Real Python Team on social media, and we’ll help.

Take the Quiz: Test your knowledge with our interactive “Documenting Python Code: A Complete Guide” quiz. You’ll receive a score upon completion to help you track your learning progress:


Documenting Python Code Guide

Interactive Quiz

Documenting Python Code: A Complete Guide

In this quiz, you'll test your understanding of documenting Python code. With this knowledge, you'll be able to effectively document your Python scripts and projects, making them more understandable and maintainable.

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Documenting Code in Python