causa prima
causa prima

Reputation: 1712

Is there a consensus on what should be documented in the class and __init__ docstrings?

I did not find any best practice about what should be documented in the class and __init__ docstrings. Sometimes I find that the constructor arguments are already documented in the class docstring, sometimes the are described in the __init__ docstring. I prefer describing the construction within the class docstring, as this is what you call when creating a new instance. But what should be documented in the __init__ methods docstring then?


edit:

I know about the google styleguide and the google docstring style example, but both do not answer my question. The docstring style example does say

The __init__ method may be documented in either the class level docstring, or as a docstring on the __init__ method itself. Either form is acceptable, but the two should not be mixed. Choose one convention to document the __init__ method and be consistent with it.

But if I choose to put the docstring of the __init__ function into the class level docstring, what should the __init__ docstring contain?

Upvotes: 105

Views: 60212

Answers (7)

Brig
Brig

Reputation: 10321

NumpyDoc Style Guide says you should document the __init__ in the class document and that the arguments of __init__ should be listed in a Parameters section.

The constructor (__init__) should also be documented here, the Parameters section of the docstring details the constructor’s parameters.

Here are examples from numpy's code base where you can see where __init__ doesn't have a docstring. Instead it shows up in the class document.

As pandas also follows Numpy Doc style, one can spot examples from pandas, too:

Upvotes: 8

dshanahan
dshanahan

Reputation: 744

The class documentation should include the public components of the object. The __init__ parameters may or may not be public, so whether they are included in the class docstring or not depends on the object design.

The full paragraph in PEP 257 states:

The docstring for a class should summarize its behavior and list the public methods and instance variables. If the class is intended to be subclassed, and has an additional interface for subclasses, this interface should be listed separately (in the docstring). The class constructor should be documented in the docstring for its __init__ method. Individual methods should be documented by their own docstring.

And the google style guide states:

Classes should have a docstring below the class definition describing the class. If your class has public attributes, they should be documented here in an Attributes section and follow the same formatting as a function’s Args section.

So the documentation determination hinges on whether the parameters for __init__ are public. If the intention of the object is for users to construct their own instances, the __init__ parameters should be documented in the class docstring. However, if an object is constructed internally then returned to the user, the class documentation should only refer to the public aspects of the object.

So the following example from google suggest that the likes_spam parameter from __init__ is public:

class SampleClass(object):
    """Summary of class here.

    Longer class information....
    Longer class information....

    Attributes:
        likes_spam: A boolean indicating if we like SPAM or not.
        eggs: An integer count of the eggs we have laid.
    """

    def __init__(self, likes_spam=False):
        """Inits SampleClass with blah."""
        self.likes_spam = likes_spam
        self.eggs = 0

    def public_method(self):
        """Performs operation blah."""

However, below the public likes_spam attribute is determined during __init__ based on two internal parameters spam_count and like_threshold. So, likes_spam is documented in the class docstring, while spam_count and like_threshold are documented in the __init__ docstring.

class SampleClass(object):
    """Summary of class here.

    Longer class information....
    Longer class information....

    Attributes:
        likes_spam: A boolean indicating if we like SPAM or not.
        eggs: An integer count of the eggs we have laid.
    """

    def __init__(self, spam_count, like_threshold=1):
        """Inits SampleClass.

        Args:
            spam_count: The amount of SPAM consumed.
            like_threshold: The threshold consumed that indicates 
                whether we like SPAM.
        """
        self.likes_spam = spam_count > like_threshold
        self.eggs = 0

    def public_method(self):
        """Performs operation blah."""

Upvotes: 25

Eric O. Lebigot
Eric O. Lebigot

Reputation: 94475

There is an official answer, in PEP 257 (the docstring PEP), which is arguably authoritative:

The class constructor should be documented in the docstring for its __init__ method.

This is quite logical, as this is the usual procedure for functions and methods, and __init__() is not an exception.

As a consequence, this puts the code and its documentation in the same place, which helps maintenance.

Finally, tools that display documentation to the user (like Jupyter, or the built-in Python shell command help()) are more likely to correctly display the documentation of your code. In practice, they do display the __init__() docstring automatically when you ask for help on the class, so this is one more reason to follow the official convention of putting the initialization documentation in __init__().

Upvotes: 38

Demis
Demis

Reputation: 5716

The actual usage of the class is initialized by a command like SampleClass(args), and no user is ever going to type in SampleClass.__init__(args), so from an end-user perspective, when they are confused, they are much more likely to type

help(SampleClass)

instead of

help(SampleClass.__init__)

So I think it makes sense to put all documentation into SampleClass's docstring.
And in __init__'s docstring put "Please see help(SampleClass) for more info" just in case there's the off chance that someone (or some program) looks at it.

Upvotes: 15

Oleiade
Oleiade

Reputation: 6274

I am not aware of any consensus on that point.

However, the sphinx autodoc module allows documentation to be generated from your docstring.Therefore it tends to enforce consistent docstring documentation.

In your case, I would document what the class is and the constructor arguments in the class docstring like:

class MyClass:
    """I am a class.
    I do funny stuff

    :type tags: dict
    :param tags: A dictionary of key-value pairs
    """

    def __init__(tags):
        self.tags = tags

Upvotes: 1

salomonderossi
salomonderossi

Reputation: 2188

I personally try to use the google styleguide when possible

When you create a new instance with __init__ it should be documented what member variables are initialized. Then other people know what they can expect when they need to access them later in their code.

Sample from the google styleguide:

class SampleClass(object):
    """Summary of class here.

    Longer class information....
    Longer class information....

    Attributes:
        likes_spam: A boolean indicating if we like SPAM or not.
        eggs: An integer count of the eggs we have laid.
    """

    def __init__(self, likes_spam=False):
        """Inits SampleClass with blah."""
        self.likes_spam = likes_spam
        self.eggs = 0

    def public_method(self):
        """Performs operation blah."""

Upvotes: 9

coralvanda
coralvanda

Reputation: 6596

Google has their own style guide for Python, which is not a bad thing to refer to. Here is a link with what they consider best practices for doc-strings: http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html

Upvotes: 0

Related Questions