Python-Sphinx:“继承"超类的方法文档 [英] Python-Sphinx: "inherit" method documentation from superclass

查看:117
本文介绍了Python-Sphinx:“继承"超类的方法文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

修改: 截至目前(Sphinx 1.4.9),似乎还没有办法告诉Sphinx做我想做的事情(请参阅问题.来自Brecht Machiels的可接受的答案以另一种方式解决了该问题,直到Sphinx有一天能够做到. /p>

说明: 我正在尝试使用sphinx-apidoc记录一个Python项目. Sphinx配置几乎是默认配置,我只添加了'sphinx.ext.autodoc'.

它通常可以工作,但是派生类不会像我期望的那样继承其超类的方法文档.

示例: 考虑一个名为project的非常简约的Python程序包.除了空的__init__.py之外,它仅包含一个文件(base.py,请参见下文)

# -*- coding: utf-8 -*
import abc


class Superclass(object):
    """The one to rule them all"""

    @abc.abstractmethod
    def give(self, ring):
        """Give out a ring"""
        pass


class Derived(Superclass):
    """Somebody has to do the work"""

    def give(self, ring):
        print("I pass the ring {} to you".format(ring))

运行sphinx-apidoc(sphinx-apidoc -o apidoc project -f)会生成以下文件:

  • apidoc/modules.rst

    project
    =======
    
    .. toctree::
       :maxdepth: 4
    
       project
    

  • apidoc/project.rst

    project package
    ===============
    
    Submodules
    ----------
    
    project.base module
    -------------------
    
    .. automodule:: project.base
        :members:
        :undoc-members:
        :show-inheritance:
    
    
    Module contents
    ---------------
    
    .. automodule:: project
        :members:
        :undoc-members:
        :show-inheritance:
    

在默认index.rst中包含apidoc/modules.rst,后跟make html会为类及其方法生成基本的html文档.不幸的是,Derived.give的文档字符串为空.

问题: 是否有一种方法可以告诉Sphinx在没有装饰符魔术的情况下获取父对象的方法文档,如解决方案

您可以通过为抽象基类使用元类来自动管理文档字符串.以下是此类元类的非常基本的实现.需要对其进行扩展以正确处理多个基类和极端情况.

# -*- coding: utf-8 -*
import abc


class SuperclassMeta(type):
    def __new__(mcls, classname, bases, cls_dict):
        cls = super().__new__(mcls, classname, bases, cls_dict)
        for name, member in cls_dict.items():
            if not getattr(member, '__doc__'):
                member.__doc__ = getattr(bases[-1], name).__doc__
        return cls


class Superclass(object, metaclass=SuperclassMeta):
    """The one to rule them all"""

    @abc.abstractmethod
    def give(self, ring):
        """Give out a ring"""
        pass


class Derived(Superclass):
    """Somebody has to do the work"""

    def give(self, ring):
        print("I pass the ring {} to you".format(ring))

与Sphinx相比,这甚至是更好的解决方案,因为在派生类上调用help()时,这也将起作用.

Edit: As of now (Sphinx 1.4.9) there seems to be no way to tell Sphinx to do what I want (see issue on GitHub). The accepted answer from Brecht Machiels solves the problem in an other way, until Sphinx might be able to do so one day.

Description: I am trying to document a Python project with sphinx-apidoc. The Sphinx config is almost default, I just included 'sphinx.ext.autodoc'.

It works in general, but derived classes do not inherit method documentation of their superclasses as I would expect it.

Example: Consider a very minimalistic Python package called project. Aside an empty __init__.py it only consists of one file (base.py, see below)

# -*- coding: utf-8 -*
import abc


class Superclass(object):
    """The one to rule them all"""

    @abc.abstractmethod
    def give(self, ring):
        """Give out a ring"""
        pass


class Derived(Superclass):
    """Somebody has to do the work"""

    def give(self, ring):
        print("I pass the ring {} to you".format(ring))

Running sphinx-apidoc (sphinx-apidoc -o apidoc project -f) generates the following files:

  • apidoc/modules.rst

    project
    =======
    
    .. toctree::
       :maxdepth: 4
    
       project
    

  • apidoc/project.rst

    project package
    ===============
    
    Submodules
    ----------
    
    project.base module
    -------------------
    
    .. automodule:: project.base
        :members:
        :undoc-members:
        :show-inheritance:
    
    
    Module contents
    ---------------
    
    .. automodule:: project
        :members:
        :undoc-members:
        :show-inheritance:
    

Including apidoc/modules.rst in the default index.rst followed by make html generates a basic html documentation for both classes and their methods. Unfortunately, the docstring of Derived.give is empty.

Question: Is there a way to tell Sphinx to take the parent's method documentation without decorator magic as described in this SO post for every single method?

解决方案

You can manage docstrings automatically by employing a metaclass for the abstract base class. The following is a very basic implementation of such a metaclass. It needs to be extended to properly handle multiple base classes and corner cases.

# -*- coding: utf-8 -*
import abc


class SuperclassMeta(type):
    def __new__(mcls, classname, bases, cls_dict):
        cls = super().__new__(mcls, classname, bases, cls_dict)
        for name, member in cls_dict.items():
            if not getattr(member, '__doc__'):
                member.__doc__ = getattr(bases[-1], name).__doc__
        return cls


class Superclass(object, metaclass=SuperclassMeta):
    """The one to rule them all"""

    @abc.abstractmethod
    def give(self, ring):
        """Give out a ring"""
        pass


class Derived(Superclass):
    """Somebody has to do the work"""

    def give(self, ring):
        print("I pass the ring {} to you".format(ring))

This is even a better solution than having Sphinx do this, because this will also work when calling help() on the derived classes.

这篇关于Python-Sphinx:“继承"超类的方法文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆