有一个关于Inherit docstrings in Python class inheritance的问题,但那里的答案涉及方法文档字符串。
我的问题是如何继承父类的文档字符串作为 __doc__
属性。用例是 Django rest framework根据您的 View 类的文档字符串,在您的 API 的 html 版本中生成很好的文档。但是在没有文档字符串的类中继承基类(带有文档字符串)时,API 不显示文档字符串。
很可能是 sphinx 和其他工具做正确的事情并为我处理文档字符串继承,但 django rest 框架查看(空).__doc__
属性。
class ParentWithDocstring(object):
"""Parent docstring"""
pass
class SubClassWithoutDoctring(ParentWithDocstring):
pass
parent = ParentWithDocstring()
print parent.__doc__ # Prints "Parent docstring".
subclass = SubClassWithoutDoctring()
print subclass.__doc__ # Prints "None"
我已经尝试过像 super(SubClassWithoutDocstring, self).__doc__
这样的东西,但它也只给我一个 None
。
最佳答案
由于您不能将新的 __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'
另一种方法是将__init__
中的__doc__
设置为实例变量:
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(已修复 issue 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'
关于python - 继承父类文档字符串作为 __doc__ 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13937500/