在Python类继承中继承docstring

在Python类继承中继承docstring,python,inheritance,documentation,Python,Inheritance,Documentation,我正在尝试用Python进行一些类继承。我希望每个类和继承的类都有好的docstring。因此,我认为对于继承类,我希望它: 继承基类docstring 可能会在docstring中附加相关的额外文档 在类继承的情况下,有没有(可能是优雅的或pythonic的)方法来进行这种docstring操作?多重继承怎么样?你不是唯一一个!不久前有一次关于comp.lang.python的讨论,并创建了一个配方。查看它 """ doc_inherit decorator Usage: class

我正在尝试用Python进行一些类继承。我希望每个类和继承的类都有好的docstring。因此,我认为对于继承类,我希望它:

  • 继承基类docstring
  • 可能会在docstring中附加相关的额外文档

在类继承的情况下,有没有(可能是优雅的或pythonic的)方法来进行这种docstring操作?多重继承怎么样?

你不是唯一一个!不久前有一次关于
comp.lang.python
的讨论,并创建了一个配方。查看它

"""
doc_inherit decorator

Usage:

class Foo(object):
    def foo(self):
        "Frobber"
        pass

class Bar(Foo):
    @doc_inherit
    def foo(self):
        pass 

Now, Bar.foo.__doc__ == Bar().foo.__doc__ == Foo.foo.__doc__ == "Frobber"
"""

from functools import wraps

class DocInherit(object):
    """
    Docstring inheriting method descriptor

    The class itself is also used as a decorator
    """

    def __init__(self, mthd):
        self.mthd = mthd
        self.name = mthd.__name__

    def __get__(self, obj, cls):
        if obj:
            return self.get_with_inst(obj, cls)
        else:
            return self.get_no_inst(cls)

    def get_with_inst(self, obj, cls):

        overridden = getattr(super(cls, obj), self.name, None)

        @wraps(self.mthd, assigned=('__name__','__module__'))
        def f(*args, **kwargs):
            return self.mthd(obj, *args, **kwargs)

        return self.use_parent_doc(f, overridden)

    def get_no_inst(self, cls):

        for parent in cls.__mro__[1:]:
            overridden = getattr(parent, self.name, None)
            if overridden: break

        @wraps(self.mthd, assigned=('__name__','__module__'))
        def f(*args, **kwargs):
            return self.mthd(*args, **kwargs)

        return self.use_parent_doc(f, overridden)

    def use_parent_doc(self, func, source):
        if source is None:
            raise NameError, ("Can't find '%s' in parents"%self.name)
        func.__doc__ = source.__doc__
        return func

doc_inherit = DocInherit 

您可以轻松地连接文档字符串:

class Foo(object):
    """
    Foo Class.
    This class foos around.
    """
    pass

class Bar(Foo):
    """
    Bar class, children of Foo
    Use this when you want to Bar around.
    parent:
    """ 
    __doc__ += Foo.__doc__
    pass

然而,这是无用的。大多数文档生成工具(包括)都已经提取了父文档字符串,包括for方法。所以你不必做任何事。

不是特别优雅,而是简单直接:

class X(object):
  """This class has a method foo()."""
  def foo(): pass

class Y(X):
  __doc__ = X.__doc__ + ' Also bar().'
  def bar(): pass
现在:


可以保留继承的docstring语法和首选顺序的混合stile可以是:

class X(object):
  """This class has a method foo()."""
  def foo(): pass

class Y(X):
  """ Also bar()."""
  __doc__ = X.__doc__ + __doc__
  def bar(): pass
与Alex的输出相同:

>>> print Y.__doc__
This class has a method foo(). Also bar().
薄冰:使用docstring会使您的模块无法使用
python-OO
,除此之外:

TypeError: cannot concatenate 'str' and 'NoneType' objects
我写这篇文章是为了提供一些简单、轻量级的工具来处理docstring继承

它还附带了一些不错的默认样式,用于合并不同类型的docstring(例如Numpy、Google和reST格式的docstring)。你也可以很容易地提供你自己的风格


重叠的docstring部分将遵从子类的部分,否则它们将以良好的格式合并在一起。

对于方法继承父类方法的docstring来说,这很好。我认为这在很多情况下都是有用的。我在考虑整个类的docstring,我想在这里继承和附加。啊,明白了。在这种情况下,大多数文档生成已经为您完成了这项工作。事实上,大多数文档工具都完成了这项工作。但是内置的help()函数没有。@MarioVilas:也许这是一个应该报告的错误?Sphinx似乎没有为我这样做,也许是因为我的父项是“私有”的,即名称以下划线开头。如果你也要为
Init docstring
这样做,在
Y
的定义中有什么方法可以做到吗?我能做到这一点的唯一方法是使用
\uuuuuu init\uuuuuu.\uuuuu doc\uuuuuuuu=X.“uuuuu init\uuuuuuuuuuuuuu+”还有另一个参数“
Y
中的
\uuuuuuuu init\uuuuuuuuuuuuuuuu>定义之后,但这似乎会弄乱格式,导致额外的空格。我无法回答,因为这个问题很不幸地结束了,但在Python 3.5中,将搜索继承树,直到找到docstring。请参阅。
TypeError: cannot concatenate 'str' and 'NoneType' objects