Inherit docstrings in Python class inheritance

I am trying to do some class inheritance in Python. I would like every class and inherited class to have good docstrings. Therefore, I believe that for an inherited class, I would like to:

  • inherits the docstring base class
  • it is possible to add relevant additional documentation to docstring

Is there any (possibly elegant or pythonic) way to do this kind of docstring manipulation in a class inheritance situation? What about multiple inheritance?

+64
python inheritance documentation
Jan 08
source share
5 answers

You are not the only one! This was discussed some time ago by comp.lang.python , and a recipe was created. Check here .

 """ doc_inherit decorator Usage: class Foo(object): def foo(self): "Frobber" pass class Bar(Foo): @doc_inherit def foo(self): pass Now, Bar.foo.__doc__ == Bar().foo.__doc__ == Foo.foo.__doc__ == "Frobber" """ from functools import wraps class DocInherit(object): """ Docstring inheriting method descriptor The class itself is also used as a decorator """ def __init__(self, mthd): self.mthd = mthd self.name = mthd.__name__ def __get__(self, obj, cls): if obj: return self.get_with_inst(obj, cls) else: return self.get_no_inst(cls) def get_with_inst(self, obj, cls): overridden = getattr(super(cls, obj), self.name, None) @wraps(self.mthd, assigned=('__name__','__module__')) def f(*args, **kwargs): return self.mthd(obj, *args, **kwargs) return self.use_parent_doc(f, overridden) def get_no_inst(self, cls): for parent in cls.__mro__[1:]: overridden = getattr(parent, self.name, None) if overridden: break @wraps(self.mthd, assigned=('__name__','__module__')) def f(*args, **kwargs): return self.mthd(*args, **kwargs) return self.use_parent_doc(f, overridden) def use_parent_doc(self, func, source): if source is None: raise NameError, ("Can't find '%s' in parents"%self.name) func.__doc__ = source.__doc__ return func doc_inherit = DocInherit 
+31
Jan 08 '10 at 4:51
source share

You can easily concatenate docstrings:

 class Foo(object): """ Foo Class. This class foos around. """ pass class Bar(Foo): """ Bar class, children of Foo Use this when you want to Bar around. parent: """ __doc__ += Foo.__doc__ pass 

However, it is useless. Most documentation tools ( Sphinx and Epydoc enabled) will already pull out the parent docstring, including for methods. Therefore, you do not need to do anything.

+21
Jan 08 '10 at 4:55
source share

Not particularly elegant, but simple and straightforward:

 class X(object): """This class has a method foo().""" def foo(): pass class Y(X): __doc__ = X.__doc__ + ' Also bar().' def bar(): pass 

Now:

 >>> print Y.__doc__ This class has a method foo(). Also bar(). 
+3
Jan 08 '10 at 4:59
source share

A mixed structure that can preserve both the inherited docstring syntax and the preferred order can be:

 class X(object): """This class has a method foo().""" def foo(): pass class Y(X): """ Also bar().""" __doc__ = X.__doc__ + __doc__ def bar(): pass 

With the same output as Alex one:

 >>> print Y.__doc__ This class has a method foo(). Also bar(). 

Thin ice: playing with docstring may make your module unusable with python -OO , expect some:

 TypeError: cannot concatenate 'str' and 'NoneType' objects 
+2
Jun 27 '13 at 21:31 on
source share

I wrote custom_inherit to provide simple, easy tools for handling docstring inheritance.

It also contains some good default styles for merging different types of docstrings (e.g. Nump, Google and RTT formatted docstrings). You can also easily create your own style.

Overlapping docstring sections will be deferred to the child section, otherwise they will be merged along with good formatting.

-one
Jan 09 '17 at 23:54 on
source share



All Articles