简体   繁体   English

Sphinx文档模块属性

[英]Sphinx document module properties

I have a module that should have a @property , I solved this by setting a class as the module. 我有一个应该有@property的模块,我通过将类设置为模块来解决这个问题。 I got the idea from this answer: Lazy module variables--can it be done? 我从这个答案中得到了一个想法: 懒惰的模块变量 - 可以做到吗?

I wanted this to be repeatable and easy to use so I made a metaclass for it. 我希望这个可重复且易于使用,所以我为它制作了一个元类。 This works like a charm. 这就像一个魅力。

The problem is that when using Sphinx to generate documentation properties don't get documented. 问题是,当使用Sphinx生成文档属性时,请不要记录。 Everything else is documented as expected. 其他所有内容都按预期记录。 I have no idea how to fix this, maybe this is a problem with Sphinx? 我不知道如何解决这个问题,也许这是Sphinx的一个问题?

The module: 模块:

import sys
import types

class ClassAsModule(type):
    def __new__(cls, name, bases, attrs):
        # Make sure the name of the class is the module name.
        name = attrs.pop('__module__')
        # Create a class.
        cls = type.__new__(cls, name, bases, attrs)
        # Instantiate the class and register it.
        sys.modules[name] = cls = cls(name)
        # Update the dict so dir works properly
        cls.__dict__.update(attrs)

class TestClass(types.ModuleType):
    """TestClass docstring."""
    __metaclass__ = ClassAsModule
    @property
    def some_property(self):
        """Property docstring."""
        pass
    def meth():
        """meth doc"""
        pass

And a copy-paste to generate/view Sphinx documentation: 以及用于生成/查看Sphinx文档的复制粘贴:

sphinx-apidoc . -o doc --full
sphinx-build doc html
xdg-open html/module.html

The most essential part is to document the class' properties. 最重要的部分是记录班级的属性。 Bonus points to also document original module members. 奖励指向还记录原始模块成员。

EDIT: The class should be documented as the module it is in. The class is used this way and should thus appear this way in Sphinx. 编辑:该类应记录为它所在的模块。该类以这种方式使用,因此应该以这种方式出现在Sphinx中。

Example of desired output: 期望输出的示例:

Module Foo
    TestClass docstring.

    some_property
        Property docstring.

    meth()
        meth doc

EDIT 2: I found something that may aid in finding a solution. 编辑2:我找到了一些可能有助于找到解决方案的东西。 When having a regular module foo with the following content: 当具有以下内容的常规模块foo时:

#: Property of foo
prop = 'test'

Sphinx documents this like: Sphinx记录如下:

foo.prop = 'test'
    Property of foo

The same works if prop is an attribute of a class. 如果prop是类的属性,则同样有效。 I haven't figured out why it doesn't work in my special case. 我还没弄清楚为什么它在我的特殊情况下不起作用。

Here's my understanding. 这是我的理解。

The theory is: making a mutant your class act like a module this (a bit hacky) way makes sphinx think that he doesn't need (to parse) properties from modules (because it's a class-level paradigm). 理论是:使 一个突变体 你的类就像一个模块这个(有点hacky)方式使得sphinx认为他不需要(解析)模块中的属性(因为它是一个类级别的范例)。 So, for sphinx, TestClass is a module. 因此,对于sphinx, TestClass是一个模块。

First of all, to make sure that the culprit is the code for making a class act like a module - let's remove it: 首先,要确保罪魁祸首是使类像模块一样的代码 - 让我们删除它:

class ClassAsModule(type):
    pass

we'll see in docs: 我们将在docs中看到:

package Package
    script Module

    class package.script.ClassAsModule
        Bases: type

    class package.script.TestClass
        Bases: module

        TestClass docstring.

        meth()
            meth doc

        some_property
            Property docstring.

As you see, sphinx read the property without any problems. 如您所见,sphinx读取属性没有任何问题。 Nothing special here. 这里没什么特别的。


Possible solution for your problem is to avoid using @property decorator and replace it with calling property class constructor. 您的问题的可能解决方案是避免使用@property装饰器并将其替换为调用property类构造函数。 Eg: 例如:

import sys
import types

class ClassAsModule(type):
    def __new__(cls, name, bases, attrs):
        # Make sure the name of the class is the module name.
        name = attrs.pop('__module__')
        # Create a class.
        cls = type.__new__(cls, name, bases, attrs)
        # Instantiate the class and register it.
        sys.modules[name] = cls = cls(name)
        # Update the dict so dir works properly
        cls.__dict__.update(attrs)


class TestClass(types.ModuleType):
    """TestClass docstring."""
    __metaclass__ = ClassAsModule

    def get_some_property(self):
        """Property docstring."""
        pass

    some_property = property(get_some_property)

    def meth(self):
        """meth doc"""
        pass

For this code sphinx generates: 对于此代码,sphinx生成:

package Package
    script Module
        TestClass docstring.

            package.script.get_some_property(self)
                Property docstring.

            package.script.meth(self)
                meth doc

May be the answer is a piece of nonsense, but I hope it'll point you to the right direction. 答案可能是一个废话,但我希望它会指向正确的方向。

The way I've found that works best is to keep the file contents the same as if you were writing a regular module, then at the end replace the embryonic module in sys.modules : 我发现最好的方法是保持文件内容和编写常规模块一样,然后在sys.modules替换胚胎模块:

"""Module docstring.  """

import sys
import types

def _some_property(self):
    pass
some_property = property(_some_property)
"""Property docstring."""

def meth():
    """meth doc"""
    pass

def _make_class_module(name):
    mod = sys.modules[name]
    cls = type('ClassModule', (types.ModuleType,), mod.__dict__)
    clsmod = cls(name)
    clsmod.__dict__.update(mod.__dict__)
    clsmod.__wrapped__ = mod
    sys.modules[name] = clsmod
_make_class_module(__name__)

Text documentation: 文字文件:

mymod Module
************

Module docstring.

mymod.meth()

   meth doc

mymod.some_property = None

   Property docstring.

For the version of Sphinx I'm using (v1.1.3), it looks like you have to apply the property constructor explicitly (you can't use it as a decorator), and the docstring has to go in the file at the top level, on the line after the constructor call that creates the property (it doesn't work as a docstring inside the property getter). 对于我正在使用的Sphinx版本(v1.1.3),看起来你必须显式地应用属性构造函数(你不能将它用作装饰器),并且docstring必须放在顶部的文件中level,在构造函数调用之后的行上创建属性(它不能作为属性getter中的docstring)。 The source is still fairly readable, though. 但是,源代码仍然具有可读性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM