Inheriting methods' docstrings in Python
docstring, inheritance, oop, python, template-method-pattern
Solution
Write a function in a class-decorator style to do the copying for you. In Python2.5, you can apply it directly after the class is created. In later versions, you can apply with the @decorator notation.
Here's a first cut at how to do it:
import types
def fix_docs(cls):
for name, func in vars(cls).items():
if isinstance(func, types.FunctionType) and not func.__doc__:
print func, 'needs doc'
for parent in cls.__bases__:
parfunc = getattr(parent, name, None)
if parfunc and getattr(parfunc, '__doc__', None):
func.__doc__ = parfunc.__doc__
break
return cls
class Animal(object):
def walk(self):
'Walk like a duck'
class Dog(Animal):
def walk(self):
pass
Dog = fix_docs(Dog)
print Dog.walk.__doc__
In newer Python versions, the last part is even more simple and beautiful:
@fix_docs
class Dog(Animal):
def walk(self):
pass
This is a Pythonic technique that exactly matches the design of existing tools in the standard library. For example, the functools.total_ordering class decorator add missing rich comparison methods to classes. And for another example, the functools.wraps decorator copies metadata from one function to another.
Problem
I have an OO hierarchy with docstrings that take as much maintenance as the code itself. E.g., ``` class Swallow(object): def airspeed(self): """Returns the airspeed (unladen)""" raise NotImplementedError class AfricanSwallow(Swallow): def airspeed(self): # whatever ``` Now, the problem is that `AfricanSwallow.airspeed` does not inherit the superclass method's docstring. I know I can keep the docstring using the template method pattern, i.e. ``` class Swallow(object): def airspeed(self): """Returns the airspeed (unladen)""" return self._ask_arthur() ``` and implementing `_ask_arthur` in each subclass. However, I was wondering whether there's another way to have docstrings be inherited, perhaps some decorator that I hadn't discovered yet?