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_docsknow 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_docsis 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?