由于您不能__doc__
为类分配新的文档字符串(至少在 CPython 中),因此您必须使用元类:
import inspect
def inheritdocstring(name, bases, attrs):
if not '__doc__' in attrs:
# create a temporary 'parent' to (greatly) simplify the MRO search
temp = type('temporaryclass', bases, {})
for cls in inspect.getmro(temp):
if cls.__doc__ is not None:
attrs['__doc__'] = cls.__doc__
break
return type(name, bases, attrs)
是的,我们跳过了一两个额外的环节,但是上面的元类会找到正确的,__doc__
但复杂的你制作你的继承图。
用法:
>>> class ParentWithDocstring(object):
... """Parent docstring"""
...
>>> class SubClassWithoutDocstring(ParentWithDocstring):
... __metaclass__ = inheritdocstring
...
>>> SubClassWithoutDocstring.__doc__
'Parent docstring'
另一种方法是将__doc__
in设置__init__
为实例变量:
def __init__(self):
try:
self.__doc__ = next(cls.__doc__ for cls in inspect.getmro(type(self)) if cls.__doc__ is not None)
except StopIteration:
pass
然后至少您的实例有一个文档字符串:
>>> class SubClassWithoutDocstring(ParentWithDocstring):
... def __init__(self):
... try:
... self.__doc__ = next(cls.__doc__ for cls in inspect.getmro(type(self)) if cls.__doc__ is not None)
... except StopIteration:
... pass
...
>>> SubClassWithoutDocstring().__doc__
'Parent docstring'
从 Python 3.3(修复问题 12773)开始,您终于可以__doc__
只设置自定义类的属性,因此您可以使用类装饰器:
import inspect
def inheritdocstring(cls):
for base in inspect.getmro(cls):
if base.__doc__ is not None:
cls.__doc__ = base.__doc__
break
return cls
然后可以这样应用:
>>> @inheritdocstring
... class SubClassWithoutDocstring(ParentWithDocstring):
... pass
...
>>> SubClassWithoutDocstring.__doc__
'Parent docstring'