Documentation
Good documentation can turn a project into something that people can use, understand, and maintain. It lowers the barrier for new contributors, clarifies how and why public APIs behave the way they do, and makes it easier to track changes as your project evolves. Without good documentation, even well-written code can quickly become a game of guesswork, scaring away users and contributors.
Here are some best practices that you can apply while documenting your Python code:
- Document the public API of your project. Add meaningful docstrings to public packages, modules, functions, methods, and classes. Focus on what each object does, its arguments and return values, and when it can fail or raise exceptions. This practice makes your project easier to use and safer to change.
- Write a clear
READMEfile with usage examples. Add aREADMEfile that explains what the project does, how to install it, how to run simple examples, and where to find more documentation. Small, concrete code samples are often more helpful and to the point than long descriptions. - Separate different types of documentation. Use docstrings to describe public APIs and inline comments sparingly to explain non-obvious implementation details. Keep tutorials, how-to guides, and broader explanations in external documentation.
- Keep documentation close to the code and generate it automatically. Store documentation alongside the code and use tools like Sphinx or MkDocs (with appropriate plugins) to build HTML documentation from docstrings and markup files. This reduces duplication and helps keep your documentation in sync with the code.
- Update documentation as part of your development cycle. Treat documentation as part of each feature. When you implement changes, update the relevant docstrings and external documentation at the same time. This helps prevent documentation from drifting out of date.
To see the impact of documentation on usability, consider the following hypothetical function:
🔴 Avoid this:
def send(email, retries=3):
# Send email
# Implementation...
This function provides no clear information on what it does or how to use it. It has a vague name, the comment is incomplete, and the user must guess how to call it, what happens in case of failure, and whether the function returns anything useful.
✅ Favor this:
def send_welcome_email(address: str, *, retries: int = 3) -> None:
"""Send a welcome email to a new user.
Args:
address (str): Destination email address.
retries (int): Number of times to retry on transient errors.
Raises:
ValueError: If the address is empty or invalid.
EmailDeliveryError: If sending fails after all retries.
"""
# Implementation...
In this version, the function name clearly states its purpose. The docstring explains what the function does, how to call it, and what the arguments mean. It also states what callers can expect in terms of errors.
Documentation tools like Sphinx, or MkDocs with suitable plugins, can extract this docstring and include it in a generated API reference automatically.
Related Resources
Tutorial
Documenting Python Code: A Complete Guide
A complete guide to documenting Python code. Whether you're documenting a small script or a large project, whether you're a beginner or seasoned Pythonista, this guide will cover everything you need to know.
For additional information on related topics, take a look at the following resources:
- Build Your Python Project Documentation With MkDocs (Tutorial)
- Creating Great README Files for Your Python Projects (Tutorial)
- Document Your Python Code and Projects With ChatGPT (Tutorial)
- Python's doctest: Document and Test Your Code at Once (Tutorial)
- Documenting Code in Python (Course)
- Documenting Python Code: A Complete Guide (Quiz)
- Building Python Project Documentation With MkDocs (Course)
- Creating Great README Files for Your Python Projects (Quiz)