On Thu, Jul 16, 2009 at 9:13 PM, Jean-Paul Calderone<exar...@divmod.com> wrote: > On Fri, 17 Jul 2009 11:01:49 +1000, Ben Finney <ben+pyt...@benfinney.id.au> > wrote: >> >> Howdy all, >> >> The following is a common idiom:: >> >> class FooGonk(object): >> def frobnicate(self): >> """ Frobnicate this gonk. """ >> basic_implementation(self.wobble) >> >> class BarGonk(FooGonk): >> def frobnicate(self): >> special_implementation(self.warble) >> >> The docstring for ‘FooGonk.frobnicate’ is, intentionally, perfectly >> applicable to the ‘BarGonk.frobnicate’ method also. Yet in overriding >> the method, the original docstring is not associated with it. >> >> Ideally there would be a way to specify that the docstring should be >> inherited. The best I can come up with is:: >> >> class BarGonk(FooGonk): >> def frobnicate(self): >> special_implementation(self.warble) >> frobnicate.__doc__ = FooGonk.frobnicate.__doc__ >> >> but that violates DRY (the association between BarGonk and FooGonk is >> being repeated), puts the docstring assignment awkwardly after the end >> of the method instead of at the beginning where docstrings normally go, >> and reads poorly besides. >> >> What is the most Pythonic, DRY-adherent, and preferably least-ugly >> approach to override a method, but have the same docstring on both >> methods? >> > > How about this? > > class BarGonk(FooGonk): > @inherit_docstring > def frobnicate(self): > special_implementation(self.warble) > > The implementation of "inherit_docstring" is left as an exercise for the > reader (it's not utterly trivial, I admit, as "FooGonk" will not readily > be at hand, but it is still possible). > > By the way, I don't think this is a particularly good idea. Presumably > there is a reason your implementation is special. It would probably be > better if this were reflected in the docstring somehow. Perhaps this > idea is a better one: > > class BarGonk(FooGonk): > @append_to_docstring > def frobnicate(self): > """ > This implementation takes the warble into consideration. > """ > special_implementation(self.warble) > > With the result of BarGonk.frobnicate.__doc__ being set to: > > > Frobnicate this gonk. > > This implementation takes the warble into consideration.
Another way is to use a metaclass. Have its __new__ method loop through all attributes and compare those with what is already defined in bases. If you find a match, copy the __doc__ attribute. The advantage here is that it will work for all methods without any additional code, not counting the "__metaclass__ = ..." line. If you define a metaclass for the base, then no modifications are required for any subclasses. I do agree, however, that the best thing to do is to write a very short explanation for what the override is for. - Max -- http://mail.python.org/mailman/listinfo/python-list