I had an idea for a simple decorator that would probably not be very useful (feel free to comments on that, but it's not my main focus here). Regardless of that, I think it'd show how to achieve certain things and these are my main interest.
The idea: A decorator @inherit_docs
that would simply assign method's __doc__
from the one with the same name in the first parent of the class that has it.
For example, let's say that we have this:
class A:
def foo(self):
"""
Return something smart.
"""
return ...
Now, I want this:
class B(A):
@inherit_docs
def foo(self):
# Specifically for `B`, the "smart" thing is always 17,
# so the docstring still holds even though the code is different.
return 17
to be equivalent to this:
class B(A):
def foo(self):
"""
Return something smart.
"""
# Specifically for `B`, the "smart" thing is always 17,
# so the docstring still holds even though the code is different.
return 17
One purpose of this could be to have a base class that declares some functionality and then its inherited classes implement this functionality for different types of data (polymorphism). The methods are doing the same thing, so automating docstrings consistency would be nice. help
itself deals with it ok, but B.foo.__doc__
does not (B.foo
without a docstring has that value as None
).
The problems here (and the main reasons why I am interested in it) are:
- How can
inherit_docs
know which class it is in (so, how can it now aboutB
)? - How can it get anything about the class (in this case, it's parents) when the class itself doesn't exist at the moment when
@inherit_docs
is executed?
I could likely MacGyver something with metaclasses, but that would mean that the decorator works only on the classes that inherit some class made specifically for this purpose, which is ugly.
I could also have it do nothing when @inherit_docs
is called, but then do something when foo
itself is called. This would normally work fine (because the call would get self
and then play with it or with type(self)
), but that won't help in this case, as B.foo.__doc__
or help(B.foo)
do not call foo
itself.
Is this even possible and, if so, how?