Is it possible to add a documentation string to a namedtuple in an easy manner?
I tried
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
"""
A point in 2D space
"""
# Yet another test
"""
A(nother) point in 2D space
"""
Point2 = namedtuple("Point2", ["x", "y"])
print Point.__doc__ # -> "Point(x, y)"
print Point2.__doc__ # -> "Point2(x, y)"
but that doesn't cut it. Is it possible to do in some other way?
In Python 3, no wrapper is needed, as the
__doc__
attributes of types is writable.This closely corresponds to a standard class definition, where the docstring follows the header.
This does not work in Python 2.
AttributeError: attribute '__doc__' of 'type' objects is not writable
.Since Python 3.5, docstrings for
namedtuple
objects can be updated.From the whatsnew:
In Python 3.6+ you can use:
Python 3
In Python 3, you can easily alter the doc on your namedtuple:
Which allows us to view the intent for them when we call help on them:
This is really straightforward compared to the difficulties we have accomplishing the same thing in Python 2.
Python 2
In Python 2, you'll need to
__slots__ == ()
Declaring
__slots__
is an important part that the other answers here miss .If you don't declare
__slots__
- you could add mutable ad-hoc attributes to the instances, introducing bugs.And now:
Each instance will create a separate
__dict__
when__dict__
is accessed (the lack of__slots__
won't otherwise impede the functionality, but the lightweightness of the tuple, immutability, and declared attributes are all important features of namedtuples).You'll also want a
__repr__
, if you want what is echoed on the command line to give you an equivalent object:a
__repr__
like this is needed if you create the base namedtuple with a different name (like we did above with the name string argument,'NTBase'
):To test the repr, instantiate, then test for equality of a pass to
eval(repr(instance))
Example from the documentation
The docs also give such an example, regarding
__slots__
- I'm adding my own docstring to it:This demonstrates in-place usage (like another answer here suggests), but note that the in-place usage may become confusing when you look at the method resolution order, if you're debugging, which is why I originally suggested using
Base
as a suffix for the base namedtuple:To prevent creation of a
__dict__
when subclassing from a class that uses it, you must also declare it in the subclass. See also this answer for more caveats on using__slots__
.