I am a bit confused about the difference in behavior between __doc__
and other methods:
# python 3.10.13
class Parent:
def __init__(self, doc):
self._doc = doc
def __doc__(self):
return self._doc
def __other__(self):
return self._doc
class Child(Parent):
pass
>>> print(Parent("test").__doc__())
test
>>> print(Child("test").__doc__)
None # TypeError if call __doc__() since it is not defined
>>> print(Child("test").__other__())
test
But it does not work as property either:
# python 3.10.13
class Parent:
def __init__(self, doc):
self._doc = doc
@property
def __doc__(self):
return self._doc
@property
def __other__(self):
return self._doc
class Child(Parent):
pass
>>> print(Parent("test").__doc__)
test
>>> print(Child("test").__doc__)
None
>>> print(Child("test").__other__)
test
This is mentioned and somewhat discussed here @22750354, but I need help finding out why the Child class does not inherit the method/property of __doc__
. And are there other methods like __doc__
in terms of inheritance? Thank you.
As a first approximation1, when you write
obj.a
Python attempts to lookup a
by
obj
has an attributed named a
, thenobj
's class (obj.__class__
) has an attribute a
, thenobj.__class__.__mro__
) for an attribute a
.If at any point, an attribute named a
is found, that then that object gets returned as the result. This is what is inheritance means in Python. Child classes don't copy their parents, they just delegate attribute lookups to them.
Now, whenever you define a class as
class Child(Parent):
...
that class object always gets assigned a __doc__
attribute: the docstring if one was provided, or None
otherwise.
>>> Child.__doc__ is None
True
Because of this, any lookups for the attribute __doc__
will only ever propagate up to the class level before a matching object is found. Attribute lookup will never reach the stage of checking the parent classes.
1The complete attribute lookup process is much more complicated. See 3.3.2. Customizing attribute access from the Python Data Model docs for the bigger picture.