Adding docstrings to namedtuples?

前端 未结 10 1505
死守一世寂寞
死守一世寂寞 2020-12-08 01:52

Is it possible to add a documentation string to a namedtuple in an easy manner?

I tried

from collections import namedtuple

Point = namedtuple(\"Poin         


        
相关标签:
10条回答
  • 2020-12-08 02:00

    No, you can only add doc strings to modules, classes and function (including methods)

    0 讨论(0)
  • 2020-12-08 02:05

    You can achieve this by creating a simple, empty wrapper class around the returned value from namedtuple. Contents of a file I created (nt.py):

    from collections import namedtuple
    
    Point_ = namedtuple("Point", ["x", "y"])
    
    class Point(Point_):
        """ A point in 2d space """
        pass
    

    Then in the Python REPL:

    >>> print nt.Point.__doc__
     A point in 2d space 
    

    Or you could do:

    >>> help(nt.Point)  # which outputs...
    
    Help on class Point in module nt:
    
    class Point(Point)
     |  A point in 2d space
     |  
     |  Method resolution order:
     |      Point
     |      Point
     |      __builtin__.tuple
     |      __builtin__.object
     ...
    

    If you don't like doing that by hand every time, it's trivial to write a sort-of factory function to do this:

    def NamedTupleWithDocstring(docstring, *ntargs):
        nt = namedtuple(*ntargs)
        class NT(nt):
            __doc__ = docstring
        return NT
    
    Point3D = NamedTupleWithDocstring("A point in 3d space", "Point3d", ["x", "y", "z"])
    
    p3 = Point3D(1,2,3)
    
    print p3.__doc__
    

    which outputs:

    A point in 3d space
    
    0 讨论(0)
  • 2020-12-08 02:05

    In Python 3, no wrapper is needed, as the __doc__ attributes of types is writable.

    from collections import namedtuple
    
    Point = namedtuple('Point', 'x y')
    Point.__doc__ = '''\
    A 2-dimensional coordinate
    
    x - the abscissa
    y - the ordinate'''
    

    This closely corresponds to a standard class definition, where the docstring follows the header.

    class Point():
        '''A 2-dimensional coordinate
    
        x - the abscissa
        y - the ordinate'''
        <class code>
    

    This does not work in Python 2.

    AttributeError: attribute '__doc__' of 'type' objects is not writable.

    0 讨论(0)
  • 2020-12-08 02:09

    In Python 3.6+ you can use:

    class Point(NamedTuple):
        """
        A point in 2D space
        """
        x: float
        y: float
    
    0 讨论(0)
  • 2020-12-08 02:10

    Since Python 3.5, docstrings for namedtuple objects can be updated.

    From the whatsnew:

    Point = namedtuple('Point', ['x', 'y'])
    Point.__doc__ += ': Cartesian coodinate'
    Point.x.__doc__ = 'abscissa'
    Point.y.__doc__ = 'ordinate'
    
    0 讨论(0)
  • 2020-12-08 02:15

    I created this function to quickly create a named tuple and document the tuple along with each of its parameters:

    from collections import namedtuple
    
    
    def named_tuple(name, description='', **kwargs):
        """
        A named tuple with docstring documentation of each of its parameters
        :param str name: The named tuple's name
        :param str description: The named tuple's description
        :param kwargs: This named tuple's parameters' data with two different ways to describe said parameters. Format:
            <pre>{
                str: ( # The parameter's name
                    str, # The parameter's type
                    str # The parameter's description
                ),
                str: str, # The parameter's name: the parameter's description
                ... # Any other parameters
            }</pre>
        :return: collections.namedtuple
        """
        parameter_names = list(kwargs.keys())
    
        result = namedtuple(name, ' '.join(parameter_names))
    
        # If there are any parameters provided (such that this is not an empty named tuple)
        if len(parameter_names):
            # Add line spacing before describing this named tuple's parameters
            if description is not '':
                description += "\n"
    
            # Go through each parameter provided and add it to the named tuple's docstring description
            for parameter_name in parameter_names:
                parameter_data = kwargs[parameter_name]
    
                # Determine whether parameter type is included along with the description or
                # if only a description was provided
                parameter_type = ''
                if isinstance(parameter_data, str):
                    parameter_description = parameter_data
                else:
                    parameter_type, parameter_description = parameter_data
    
                description += "\n:param {type}{name}: {description}".format(
                    type=parameter_type + ' ' if parameter_type else '',
                    name=parameter_name,
                    description=parameter_description
                )
    
                # Change the docstring specific to this parameter
                getattr(result, parameter_name).__doc__ = parameter_description
    
        # Set the docstring description for the resulting named tuple
        result.__doc__ = description
    
        return result
    

    You can then create a new named tuple:

    MyTuple = named_tuple(
        "MyTuple",
        "My named tuple for x,y coordinates",
        x="The x value",
        y="The y value"
    )
    

    Then instantiate the described named tuple with your own data, ie.

    t = MyTuple(4, 8)
    print(t) # prints: MyTuple(x=4, y=8)
    

    When executing help(MyTuple) via the python3 command line the following is shown:

    Help on class MyTuple:
    
    class MyTuple(builtins.tuple)
     |  MyTuple(x, y)
     |
     |  My named tuple for x,y coordinates
     |
     |  :param x: The x value
     |  :param y: The y value
     |
     |  Method resolution order:
     |      MyTuple
     |      builtins.tuple
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __getnewargs__(self)
     |      Return self as a plain tuple.  Used by copy and pickle.
     |
     |  __repr__(self)
     |      Return a nicely formatted representation string
     |
     |  _asdict(self)
     |      Return a new OrderedDict which maps field names to their values.
     |
     |  _replace(_self, **kwds)
     |      Return a new MyTuple object replacing specified fields with new values
     |
     |  ----------------------------------------------------------------------
     |  Class methods defined here:
     |
     |  _make(iterable) from builtins.type
     |      Make a new MyTuple object from a sequence or iterable
     |
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |
     |  __new__(_cls, x, y)
     |      Create new instance of MyTuple(x, y)
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  x
     |      The x value
     |
     |  y
     |      The y value
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |  
     |  _fields = ('x', 'y')
     |  
     |  _fields_defaults = {}
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from builtins.tuple:
     |  
     |  __add__(self, value, /)
     |      Return self+value.
     |  
     |  __contains__(self, key, /)
     |      Return key in self.
     |  
     |  __eq__(self, value, /)
     |      Return self==value.
     |  
     |  __ge__(self, value, /)
     |      Return self>=value.
     |  
     |  __getattribute__(self, name, /)
     |      Return getattr(self, name).
     |  
     |  __getitem__(self, key, /)
     |      Return self[key].
     |  
     |  __gt__(self, value, /)
     |      Return self>value.
     |  
     |  __hash__(self, /)
     |      Return hash(self).
     |  
     |  __iter__(self, /)
     |      Implement iter(self).
     |  
     |  __le__(self, value, /)
     |      Return self<=value.
     |  
     |  __len__(self, /)
     |      Return len(self).
     |  
     |  __lt__(self, value, /)
     |      Return self<value.
     |  
     |  __mul__(self, value, /)
     |      Return self*value.
     |  
     |  __ne__(self, value, /)
     |      Return self!=value.
     |  
     |  __rmul__(self, value, /)
     |      Return value*self.
     |  
     |  count(self, value, /)
     |      Return number of occurrences of value.
     |  
     |  index(self, value, start=0, stop=9223372036854775807, /)
     |      Return first index of value.
     |      
     |      Raises ValueError if the value is not present.
    

    Alternatively, you can also specify the parameter's type via:

    MyTuple = named_tuple(
        "MyTuple",
        "My named tuple for x,y coordinates",
        x=("int", "The x value"),
        y=("int", "The y value")
    )
    
    0 讨论(0)
提交回复
热议问题