I am a bit confused by the PEP257 standard for documenting classes.
It says, "The docstring for a class should summarize its behavior and list the public methods and instance variables"
But it also says that all functions should have dosctrings (which, of course, I want, so that help() works).
But this seems to involve duplication i.e.
class foo:
"""A class
Attributes
----------
bar : str
A string
Methods
-------
__init__(fish):
Constructor, fish is a str which self.bar will be set to.
baz():
A function which does blah
"""
def __init__(self, fish):
"""
Constructs an XRTProductRequest object.
Parameters
----------
fish : str
A string, which the self.bar attribute will be set to.
"""
etc...
This then is rather error prone because it means that when I realise that __init__
also needs to recieve an int, then I have to remember to update the docs in 2 places, which I can guarantee I will forget.
It also makes the pydoc output duplicated: it prints my class docstring, but then says, "Methods defined here" and goes on to list all of the methods, via their own docstrings.
So, is this duplication really part of PEP257, or am I mis-reading it? Should I drop the "Methods"section of the class docstring, since each method has its own docstring? Or is this duplication really part of the standard?
TIA
Class method docstrings should contain the following: A brief description of what the method is and what it's used for. Any arguments (both required and optional) that are passed including keyword arguments. Label any arguments that are considered optional or have a default value.
Docstrings are not necessary for non-public methods, but you should have a comment that describes what the method does. This comment should appear after the "def" line.
A docstring is a string literal that occurs as the first statement in a module, function, class, or method definition. Such a docstring becomes the __doc__ special attribute of that object. All modules should normally have docstrings, and all functions and classes exported by a module should also have docstrings.
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.
Yes just drop the methods section from the class docstring. I've never ever seen something like that used.(It is used in few places in the standard library.) The class docstring needs to just describe the class and the docstring of individual methods then handle describing themselves.
Also the wording in the PEP to me means that the class docstring "should" list the public methods, but not describe them in any other way.(This is also how the above standard library example does it.) But as said, I would never even do that, since the code speaks for itself and that kind of listing is bound to get out-of-date.
Final note: I personally prefer to use the Google docstring style, because to me it's the clearest and cleanest.
example:
class Animal:
"""
A class used to represent an Animal
...
Attributes
----------
says_str : str
a formatted string to print out what the animal says
name : str
the name of the animal
sound : str
the sound that the animal makes
num_legs : int
the number of legs the animal has (default 4)
Methods
-------
says(sound=None)
Prints the animals name and what sound it makes
"""
says_str = "A {name} says {sound}"
def __init__(self, name, sound, num_legs=4):
"""
Parameters
----------
name : str
The name of the animal
sound : str
The sound the animal makes
num_legs : int, optional
The number of legs the animal (default is 4)
"""
self.name = name
self.sound = sound
self.num_legs = num_legs
def says(self, sound=None):
"""Prints what the animals name is and what sound it makes.
If the argument `sound` isn't passed in, the default Animal
sound is used.
Parameters
----------
sound : str, optional
The sound the animal makes (default is None)
Raises
------
NotImplementedError
If no sound is set for the animal or passed in as a
parameter.
"""
if self.sound is None and sound is None:
raise NotImplementedError("Silent Animals are not supported!")
out_sound = self.sound if sound is None else sound
print(self.says_str.format(name=self.name, sound=out_sound))
Yep, listing methods in the class docstring, then each method again documented, according to this standard. I reccomend using sphinx, though: https://www.sphinx-doc.org/en/master/contents.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With