Override a method but inherit the docstring
Maxim Khitrov
mkhitrov at gmail.com
Thu Jul 16 21:21:16 EDT 2009
On Thu, Jul 16, 2009 at 9:13 PM, Jean-Paul Calderone<exarkun at divmod.com> wrote:
> On Fri, 17 Jul 2009 11:01:49 +1000, Ben Finney <ben+python at 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
More information about the Python-list
mailing list