Writing clear, consistent docstrings in Python helps others understand your code’s purpose, parameters, and outputs. In this guide on how to write docstrings in Python, you’ll learn about best practices, standard formats, and common pitfalls to avoid, ensuring your documentation is accessible to users and tools alike.
By the end of this tutorial, you’ll understand that:
- Docstrings are strings used to document your Python code and can be accessed at runtime.
- Python comments and docstrings have important differences.
- One-line and multiline docstrings are classifications of docstrings.
- Common docstring formats include reStructuredText, Google-style, NumPy-style, and doctest-style.
- Antipatterns such as inconsistent formatting should be avoided when writing docstrings.
Explore the following sections to see concrete examples and detailed explanations for crafting effective docstrings in your Python projects.
Get Your Code: Click here to download the free sample code that shows you how to write docstrings in Python.
Take the Quiz: Test your knowledge with our interactive “How to Write Docstrings in Python” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
How to Write Docstrings in PythonTest your knowledge of Python docstrings, including syntax, conventions, formats, and how to access and generate documentation.
Getting Started With Docstrings in Python
Python docstrings are string literals that show information regarding Python functions, classes, methods, and modules, allowing them to be properly documented. They are placed immediately after the definition line in triple double quotes ("""
).
Their use and convention are described in PEP 257, which is a Python Enhancement Proposal (PEP) that outlines conventions for writing docstrings. Docstrings don’t follow a strict formal style. Here’s an example:
docstring_format.py
def determine_magic_level(magic_number):
"""
Multiply a wizard's favorite number by 3 to reveal their magic level.
"""
return magic_number * 3
Docstrings are a built-in means of documentation. While this may remind you of comments in Python, docstrings serve a distinct purpose. If you’re curious and would like to see a quick breakdown of the differences now, open the collapsible section below.
Python comments and docstrings seem a lot alike, but they’re actually quite different in a number of ways because they serve different purposes:
Comments | Docstrings |
---|---|
Begin with # |
Are enclosed in triple quotes (""" ) |
Consist of notes and reminders written by developers for other developers | Provide documentation for users and tools |
Are ignored by the Python interpreter | Are stored in .__doc__ and accessible at runtime |
Can be placed anywhere in code | Are placed at the start of modules, classes, and functions |
To summarize, comments explain parts of an implementation that may not be obvious or that record important notes for other developers. Docstrings describe modules, classes, and functions so users and tools can access that information at runtime.
So, while comments and docstrings may look similar at first glance, their purpose and behavior in Python are different. Next, you’ll look at one-line and multiline docstrings.
One-Line vs Multiline Docstrings
Docstrings are generally classified as either one-line or multiline. As the names suggest, one-line docstrings take up only a single line, while multiline docstrings span more than one line. While this may appear to be a slight difference, how you use and format them in your code matters.
An important formatting rule from PEP 257 is that one-line docstrings should be concise, while multiline docstrings should have their closing quotes on a new line. You may resort to a one-line docstring for relatively straightforward programs like the one below:
one_line_docstring.py
import random
def picking_hat():
"""Return a random house name."""
houses = ["Gryffindor", "Hufflepuff", "Ravenclaw", "Slytherin"]
return random.choice(houses)
In this example, you see a program that returns a random house as depicted in the classic Harry Potter stories. This is a good example for the use of one-line docstrings.
You use multiline docstrings when you have to provide a more thorough explanation of your code, which is helpful for other developers. Generally, a docstring should contain parameters, return value details, and a summary of the code.
You’re free to format docstrings as you like. That being said, you’ll learn later that there are common docstring formats that you may follow. Here’s an example of a multiline docstring:
multiline_docstring.py
def get_harry_potter_book(publication_year, title):
"""
Retrieve a Harry Potter book by its publication year and name.
Parameters:
publication_year (int): The year the book was published.
title (str): The title of the book.
Returns:
str: A sentence describing the book and its publication year.
"""
return f"The book {title!r} was published in the year {publication_year}."
As you can see, the closing quotes for this multiline docstring appear on a separate line. Now that you understand the difference between one-line and multiline docstrings, you’ll learn how to access docstrings in your code.
Ways to Access Docstrings in Python
Unlike code comments, docstrings aren’t ignored by the interpreter. They become a part of the program and serve as associated documentation for anyone who wants to understand your program and what it does. That’s why knowing how to access docstrings is so useful. Python provides two built-in ways to access docstrings: the .__doc__
attribute and the help()
function.
The .__doc__
Attribute
Say you wanted to access the documentation for the math
module. You could do so in the following way:
>>> import math
>>> print(math.__doc__)
This module provides access to the mathematical functions
defined by the C standard.
To illustrate further, you could try accessing the .__doc__
attribute for the get_harry_potter_book()
function from the previous example, which would generate this:
>>> from multiline_docstring import get_harry_potter_book
>>> print(get_harry_potter_book.__doc__)
Retrieve a Harry Potter book by its publication year and name.
Parameters:
publication_year (int): The year the book was published.
title (str): The title of the book.
Returns:
str: A sentence describing the book and its publication year
As you can see, using .__doc__
gives you information about an object at a glance. However, if you’re looking to obtain more robust documentation, then you can use the help()
function.
The help()
Function
The built-in help()
function in Python provides interactive access to an object’s documentation, including more detailed metadata than what’s available through the .__doc__
attribute alone.
For example, you can retrieve more thorough documentation of the math
module by running the following code:
>>> import math
>>> help(math)
Help on built-in module math:
NAME
math
DESCRIPTION
This module provides access to the mathematical functions
defined by the C standard.
FUNCTIONS
acos(x, /)
Return the arc cosine (measured in radians) of x.
The result is between 0 and pi.
acosh(x, /)
Return the inverse hyperbolic cosine of x.
-- More --
You can also use help()
with your own functions that include either one-line or multiline docstrings. This is a great way to see how your documentation reads from the perspective of someone using your code for the first time.
Now, try using the help()
function to retrieve the docstring information of get_harry_potter_book()
:
>>> from multiline_docstring import get_harry_potter_book
>>> help(get_harry_potter_book)
Help on function get_harry_potter_book in module multiline_docstring:
get_harry_potter_book(publication_year, title)
Retrieve a Harry Potter book by its publication year and name.
Parameters:
publication_year (int): The year the book was published.
title (str): The title of the book.
Returns:
str: A sentence describing the book and its publication year.
You’ll notice that calling .__doc__
and help()
on built-in modules like math
gives you different results, while they return the same thing for simple user-defined functions. This is because the .__doc__
attribute returns only the top-level docstring of the object, often just a summary. In contrast, help()
pulls in structured metadata and provides a more comprehensive breakdown, especially for complex objects like modules and classes.
The pydoc
Tool
Python includes a powerful built-in documentation tool called pydoc
that can display and generate documentation from your docstrings. To illustrate, imagine you have a file named magical_characters.py
that contains the following docstring:
magical_characters.py
"""A module for adding and listing magical characters."""
def add_characters(magical_being):
"""Add a new magical character."""
return f"You've added {magical_being} to the magical beings record"
if __name__ == "__main__":
print(add_characters("Gandalf"))
You can use pydoc
to view the documentation for the magical_characters
module directly in your terminal. Make sure you’re in the same directory as magical_characters.py
and run the following command to display the formatted documentation:
$ python -m pydoc magical_characters
Help on module magical_characters:
NAME
magical_characters - A module for adding and listing magical characters.
FUNCTIONS
add_characters(magical_being)
Add a new magical character.
FILE
/Users/rp/projects/python-docstrings/magical_characters.py
You can even create HTML documentation that can be viewed in a browser by adding a -w
flag, which is short for “write”. The HTML file will inherit its name from the magical_characters
module name that you pass in:
$ python -m pydoc -w magical_characters
wrote magical_characters.html
Just like before, pydoc
automatically extracts all docstrings from your magical_characters.py
file. The -w
flag tells pydoc
to write the documentation to an HTML file rather than displaying it in the terminal. The tool parses your module’s docstring, function docstrings, and class docstrings, then generates a structured web page that looks like this when you open it in the browser:

This shows that docstrings aren’t just for developers and users reading your code, but also for generating browsable, automatically generated documentation. However, there’s a catch. For pydoc
to work effectively, you have to write well-structured docstrings. You’ll learn how to do just that in the next section.
Exploring Docstring Formats in Python
While the structure of your docstrings may depend on your preference, certain conventions have emerged that standardize the way they’re written. These docstring formats help with staying consistent and allow automated tools like Sphinx and pydoc
to parse docstrings and generate navigable documentation websites.
Following a structured format could turn your plain text comments into full-featured developer documentation. Some of the most widely used of these formats are the following:
- reStructuredText docstrings
- Google-style docstrings
- NumPy-style docstrings
- Doctest-style docstrings
It’s important to learn the nuances of each of these formats so you can make the right choice for your Python projects.
reStructuredText Docstrings
reStructuredText—often abbreviated as reST—is a lightweight markup language used for writing plain text. It’s the default formatting style for inline documentation in Python, as outlined in PEP 287, and is used with tools like Sphinx to generate documentation.
When you write docstrings in reST, you need to include specific elements such as parameter names, type names, return value descriptions, and return types. You can also add headers, lists, and links to improve the structure. While reST is slightly more technical than other formats, it offers precision and can render documentation into beautiful HTML or PDFs.
Here’s a magic-infused reST docstring example for a function:
reStructuredText.py
def cast_spell(wand, incantation, target=None):
"""
Cast a magical spell using a wand and incantation.
This function simulates casting a spell. With no
target specified, it is cast into the void.
:param wand: The wand used to do the spell-casting deed.
:type wand: str
:param incantation: The words said to activate the magic.
:type incantation: str
:param target: The object or person the spell is directed at (optional).
:return: A string describing the result of the spell.
:rtype: str
:raises ValueError: If the incantation is unknown or the wand fails to work.
"""
valid_incantations = ["Lumos", "Alohomora", "Expelliarmus"]
if not wand:
raise ValueError("You can't cast spells without a wand!")
if incantation not in valid_incantations:
raise ValueError("Incantation not recognized.")
if target:
return f"{incantation} hits {target} with magic speed!"
return f"{incantation} is cast into the void...sparkles shimmer faintly"
As mentioned earlier, reST integrates with Sphinx, but its extensible design also supports other tools such as Docutils for generating automatic documentation and simple web pages.
Google-Style Docstrings
Google-style docstrings provide a clean, structured way to document your code, especially when it’s concerned with multiple parameters or returns complex values. They became popular through Google’s Python projects and other large codebases. To illustrate, imagine casting a spell that allows users to retrieve magical items with ease.
For such a program, a Google-style docstring might look like this:
google_style.py
def get_magic_items(user_id, include_potions=False):
"""
Retrieve a list of magical items for a specific user.
Args:
user_id (int): The ID of the user whose items should be retrieved.
include_potions (bool, optional): Whether to include potions.
Returns:
list[str]: A list of item names associated with the user.
"""
items = ["wand", "cloak", "crystal ball"]
if include_potions:
items.extend(["healing potion", "invisibility potion"])
return items
In this format, Args
lists parameters and their descriptions, Returns
describes the return value and its type, and Raises
(when included) shows exceptions that might be raised by the function.
Google-style docstrings shine when you need a detailed, consistent structure—especially if you’re collaborating on large projects or using documentation generators like Sphinx.
NumPy-Style Docstrings
The NumPy style of docstrings is favored in scientific and data-oriented Python projects. It uses sections with headers underlined by dashes to clearly distinguish different parts of the docstring. Here’s a NumPy-style docstring in action:
numpy_style.py
def brew_potion(ingredients, heat_level):
"""
Brew a potion using selected ingredients and heat.
Parameters
----------
ingredients : list of str
A list of magical ingredients.
heat_level : int
The intensity of the heat used for brewing.
Returns
-------
str
A description of the brewed potion.
"""
return f"A sparkling blue elixir of friendship heated at {heat_level}."
This style places emphasis on headers such as parameters, examples, and returns. It’s mostly used in academic and scientific circles with libraries like NumPy, pandas, and SciPy.
You may find NumPy-style docstrings to be an attractive choice when writing programs for data analysis, scientific computing, or any project that requires detailed, well-formatted documentation.
Doctest-Style Docstrings
The doctest-style docstring stands out among the common formats because it accomplishes two things at the same time: it documents your code and acts as a lightweight automated test suite. When you include example code in the docstring, the doctest
module verifies the examples you’ve written as part of your tests.
The built-in doctest
module ensures that the function behaves as expected. You essentially write examples in the same way they would be typed in the Python shell, and doctest
confirms if the output matches.
In the example below, a spell to undo other spells is documented so you can see the doctest format in action:
magic_spells.py
def undo_spell(spell):
"""
Reverses characters in a spell incantation, thereby undoing a spell.
Example:
>>> undo_spell("Expelliarmus")
'sumraillepxE'
>>> undo_spell("Lumos")
'somuL'
"""
return spell[::-1]
After typing out the docstring as shown above, you could run it as a test by entering it in your terminal like this:
$ python -m doctest magic_spells.py
This assumes that your file is named magic_spells.py
. If your function returns something that isn’t expected based on your docstring, then doctest
would raise an error.
While each of these styles has its advantages and disadvantages, it’s best to be consistent with whichever format you choose. In the next section, you’ll dive into standardized methods for writing docstrings to document Python modules, functions, and classes.
Writing Effective Docstrings
A good analogy for an effective docstring is a well-drawn road map that tells you where to go while on vacation in a foreign country. If you have a badly drawn map to follow while visiting, say, Harry Potter’s town, you might get lost and find yourself in a cauldron belonging to an unsavory character.
Docstrings play a similar role for your code. They inform other developers—and future you—about what your code does and how to use it.
This is a good reason why you should pay attention not only to the format but also to the content of your docstring. Following usual conventions allows for uniformity so that others can work with confidence when viewing your code. In this section, you’ll explore best practices for writing docstrings across three important parts of most Python codebases: modules, functions, and classes.
Docstrings for Modules
When you write docstrings for modules, the goal is to provide a high-level summary of what the program does. This appears at the top of your Python file and serves as an overview of its contents.
Here, you’ll add a brief description of the module’s purpose and a list of its components. You could also add references to related modules or examples of usage. Check out the example below:
navigation.py
"""
This module provides tools for creating and managing magical maps.
Example:
from navigation import build_map
build_map(["mandrake", "phoenix feather", "tree bark"], heat_level=3)
"""
It’s especially helpful if you use clear, concise descriptions and relevant examples to make it easier for readers to understand and use your module.
Docstrings for Functions
Functions are common in most codebases, so writing clear and informative docstrings for them is essential. A good function docstring should provide a summary of what the function does, along with details about its parameters, return values, and exceptions, if any. Here’s an example:
function_docstring.py
def enchant_wand(wand_type, level=1):
"""
Enhance a wand with magical properties.
Args:
wand_type (str): The type of wand to enchant.
level (int, optional): The enchantment level. Defaults to 1.
Returns:
str: A message confirming the enchantment.
Raises:
ValueError: If the enchantment level is invalid.
"""
if level < 1:
raise ValueError("Enchantment level must be at least 1.")
return f"{wand_type.title()} enchanted to level {level}!"
When you write multiline docstrings, you should always follow a one-line summary—in the imperative verb form—with a blank line. Also, don’t shy away from examples and clearly describe any exceptions and arguments, as shown above.
Docstrings for Classes
Class-level docstrings describe the overall purpose of a class, its attributes, and public methods. With class-level docstrings, you generally include a summary of the class’s purpose at the top of the class definition, as in the example below:
classes_docstring.py
class Potion:
"""
Represents a magical potion composed of various ingredients.
Attributes
----------
name : str
The name of the potion.
ingredients : list of str
A list of ingredients used in the potion.
potency : int
The strength level of the potion.
Methods
-------
brew():
Completes the potion and sets its potency.
describe():
Returns a human-readable summary of the potion.
"""
def __init__(self, name, ingredients):
self.name = name
self.ingredients = ingredients
self.potency = 0
def brew(self):
"""Simulate brewing the potion by calculating potency."""
self.potency = len(self.ingredients) * 10
def describe(self):
"""Return a string describing the potion and its strength."""
return f"{self.name} (Potency: {self.potency})"
This shows a standardized way of presenting docstrings for classes. You may wonder about the behavior of docstrings in classes when dealing with inheritance. Click the collapsible section below to find out.
When working with inheritance and subclasses, you’ll notice that class docstrings generally don’t get inherited by the subclass. For instance, consider this subclass that inherits from the Potion
class you saw earlier:
>>> from classes_docstring import Potion
>>> class MiniPotion(Potion):
... pass
>>> help(MiniPotion)
Help on class MiniPotion in module __main__:
class MiniPotion(classes_docstring.Potion)
| MiniPotion(name, ingredients)
|
| Method resolution order:
| MiniPotion
| classes_docstring.Potion
| builtins.object
|
| Methods inherited from classes_docstring.Potion:
|
| __init__(self, name, ingredients)
| Initialize self. See help(type(self)) for accurate signature.
|
| brew(self)
| Simulate brewing the potion by calculating potency.
|
-- More --
This is what it looks like if you check the MiniPotion
docstring directly:
>>> print(MiniPotion.__doc__)
None
>>> print(MiniPotion.brew.__doc__)
Simulate brewing the potion by calculating potency.
As you can see, the class docstring isn’t inherited, but method docstrings—such as brew
—are visible. To give MiniPotion
its own docstring, you can override it explicitly:
>>> class MiniPotion(Potion):
... """Represents a mini magical potion composed of tiny ingredients."""
... pass
>>> print(MiniPotion.__doc__)
Represents a mini magical potion composed of tiny ingredients.
With this, you’ve seen the nuances of docstrings when dealing with inheritance.
As you’ve seen, docstrings can behave differently in the context of inheritance. Whether you’re documenting modules, functions, or classes, it’s important to ask yourself the following questions when writing your docstrings:
- Do the docstrings help readers understand your code without needing to read every line?
- Is the formatting consistent enough to work well with documentation tools?
- Will the docstrings make your code easier to maintain in the future?
With effective docstrings, your code becomes more professional, readable and informative, enabling better collaboration and code maintenance. Unfortunately, there are pitfalls developers fall into when attempting to write effective docstrings. In the next section, you’ll learn how to avoid them.
Avoiding Docstring Antipatterns
Ignoring proper docstring formatting can confuse readers, leading to classes, modules, and functions being used incorrectly. In this section, you’ll explore three common docstring antipatterns developers fall into and learn how to avoid them with practical techniques and improved examples.
Vague Descriptions and Parameters
A key feature of good communication is the ability to convey information with clarity. When docstrings are too ambiguous, they fail to do this, leaving users with less information than intended and making them clueless about the intended purpose of the module, class, or function.
Referring to your map example from earlier, it’s like creating an elaborate map with no key or legend to help readers find their way. Vague descriptions and parameters often use generic terms like “something is done” or provide no explanation of the parameters. Here’s an example of a vague docstring:
vague_descriptions.py
def brew(item):
"""Does something with the item."""
pass
To understand why this is a bad docstring, you need to put yourself in the shoes of the reader. After reading this, you still have no idea what the parameter means, or what data type it expects. This is an example of what not to do when writing docstrings. To improve it, you could try something like this:
vague_descriptions_fix.py
def brew(potion_ingredients):
"""
Mixes the provided ingredients to brew a potion.
Args:
potion_ingredients (list of str): Ingredients needed to brew the potion.
Returns:
str: The name of the completed potion.
"""
return f"Magical potion brewed from {', '.join(potion_ingredients)}"
This version clearly explains what the function does, describes its parameter, and specifies its return value. It’s far more useful for anyone reading or working with your code. To avoid vague descriptions and parameters, don’t use generalized terms like “stuff” or “something”. Instead, choose specific terms that make it easy for readers to quickly understand what your code is about.
Inconsistent Formatting
Earlier, you learned about the different formatting styles that are used in Python docstrings. When using them, it’s crucial that you’re consistent with a chosen format in your code. For example, mixing Google-style and NumPy-style formats in the same codebase would make your docstrings difficult to follow and cause your readers to become frustrated.
In addition, if you rely on automatic documentation generators, this could lead to misinterpretations. For better readability, keep your docstrings consistent across the codebase and follow the rules of your chosen format.
Also, watch out for inconsistent indentation. In the example below, you’ll see what not to do when writing docstrings:
inconsistent_format.py
def summon(spell, caster):
"""Summons a creature.
Parameters:
spell - name of the spell
caster: name of the caster
Return:
The summoned creature
"""
Can you spot the errors in this example? The terms “Parameters” and “Return” are inconsistent with Google-style docstrings, the data types aren’t provided, and the indentation isn’t consistent. Here’s how to format it correctly:
inconsistent_format_fix.py
def summon(spell, caster):
"""
Summons a creature using the given spell.
Args:
spell (str): The name of the summoning spell.
caster (str): The name of the person casting the spell.
Returns:
str: The name of the summoned creature.
"""
This is a standardized representation of a Google-style docstring, which improves readability. To ensure you write docstrings this way, be sure to stick to a particular format in your codebase and abide by its standards.
Missing Return Value Explanations
If you don’t specify the description of the return values in your code, then the reader is left guessing. In some cases, if they really want to use your code, then they may need to walk through the entire codebase just to figure it out, which defeats the purpose of docstrings and wastes time.
To avoid this, be specific and clear about what’s being returned in your functions. This clarity can also go a long way toward preventing bugs.
Here’s an example of an incomplete docstring that doesn’t provide return value explanations:
minimal_return_details.py
def generate_shield(strength):
"""
Generates a magical shield based on input strength.
Args:
strength (int): Strength level.
"""
return f"Shield with strength {strength}"
As you can see, the return value is poorly documented. Is it a string, an object, or something else entirely? The reader would need clarity on this, as shown here:
minimal_return_details_fix.py
def generate_shield(strength):
"""
Generates a magical shield based on input strength.
Args:
strength (int): The strength level of the shield.
Returns:
str: A human-readable description of the generated shield.
"""
return f"Shield with strength {strength}"
Now it’s clear what the function returns, and the reader can save time and avoid bugs.
When writing docstrings, make sure your descriptions are clear and specific, document all parameters with their types, explain the return values, and stay consistent with your chosen format. Ideally, a reader should be able to understand the scope of your program at a glance.
Conclusion
Docstrings act as a manual for your code. Writing them effectively and according to conventions ensures that your code is professional and readable. By paying attention to how they’re written, you can avoid common pitfalls such as vague descriptions and parameters, inconsistent formatting, and missing return value descriptions. You can also generate beautiful HTML files and PDFs with well-formatted docstrings.
In this tutorial, you learned how to:
- Access a docstring at runtime using the
.__doc__
attribute - Follow conventions for one-line and multiline docstrings described in PEP 257
- Format docstrings by using triple double quotes (
"""
) - Use common docstring formats like reStructuredText, Google-style, NumPy-style, and doctest-style
- Avoid docstring antipatterns like vague descriptions, inconsistent formatting, and missing return value explanations
With effective docstrings, you help readers and tools understand your code, prevent misunderstandings, and reduce the risk of bugs.
Get Your Code: Click here to download the free sample code that shows you how to write docstrings in Python.
Frequently Asked Questions
Now that you have some experience with writing docstrings in Python, you can use the questions and answers below to check your understanding and recap what you’ve learned.
These FAQs are related to the most important concepts you’ve covered in this tutorial. Click the Show/Hide toggle beside each question to reveal the answer.
You access the .__doc__
attribute on any object, like a function or module, to view its docstring and get a summary of what it does.
You use a one-line docstring for simple, clear summaries that fit on a single line, while a multiline docstring works for more detailed explanations, with the closing quotes on a new line and optional sections for parameters and return values.
You should format docstrings by starting with a concise summary and using triple quotes. For multiline docstrings, include details about parameters and return values.
Common docstring formats include reStructuredText (reST), Google-style, NumPy-style, and doctest-style, each with its own conventions for organizing information about parameters, returns, and examples.
You should avoid vague descriptions, missing parameters or return explanations, and inconsistent formatting, as these make your documentation unclear and hard to use with automated tools.
Take the Quiz: Test your knowledge with our interactive “How to Write Docstrings in Python” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
How to Write Docstrings in PythonTest your knowledge of Python docstrings, including syntax, conventions, formats, and how to access and generate documentation.