On Jul 17, 10:52 am, Steven D'Aprano <st...@remove-this- cybersource.com.au> wrote: > > When the decorator is called, the function object is just a function > object, not a method, so there is no concept of "what class it is > destined for". >
... which points to the better solution: use a descriptor. With the doc_inherit decorator defined below, one may write class Foo(object): def foo(self): "Frobber" pass class Bar(Foo): @doc_inherit def foo(self): pass and it appears to work. The code below is a little longish because we need to do slightly different things when called for a class and for an instance. But there's no need to repeat the parent name, no need to look into namespaces (which, as you said, is probably messy and fragile), and it seems pretty readable, too. 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 Combining docstrings (as suggested by Jean-Paul Calderone), and taking proper care of classmethods and staticmethods, are left as an exercise to the reader. Have fun, Shai. -- http://mail.python.org/mailman/listinfo/python-list