Python Sphinx自动文档和装饰器成员

34 投票
9 回答
14819 浏览
提问于 2025-04-16 03:58

我正在尝试使用Sphinx来为我的Python类写文档。我是通过自动文档功能来实现的:

.. autoclass:: Bus
   :members:

虽然它能正确获取我方法的文档字符串,但那些被装饰器修饰的方法:

    @checkStale
    def open(self):
        """
        Some docs.
        """
        # Code

比如用@checkStale装饰的

def checkStale(f):
    @wraps(f)
    def newf(self, *args, **kwargs):
        if self._stale:
            raise Exception
        return f(self, *args, **kwargs)
    return newf

却显示了错误的函数原型,比如open(*args, **kwargs)

我该怎么解决这个问题呢?我原以为使用@wraps就能解决这种情况。

9 个回答

7

我刚找到一个简单的解决办法,对我来说很好用,但我也不知道为什么。如果你知道原因,可以在评论里告诉我。

from functools import wraps 

def a_decorator(f):
    """A decorator 

    Args:
        f (function): the function to wrap
    """
    @wraps(f) # use this annotation on the wrapper works like a charm
    def wrapper(*args, **kwargs):
        some code
        return ret

return wrapper

被装饰的函数和装饰器的文档都被保留了。

17

我也遇到过和celery @task装饰器一样的问题。

你可以通过在你的rst文件中添加正确的函数签名来解决这个问题,像这样:

.. autoclass:: Bus
    :members:

    .. automethod:: open(self)
    .. automethod:: some_other_method(self, param1, param2)

这样做仍然会自动记录没有装饰器的成员。

这个内容在sphinx的文档中有提到,链接在这里:http://www.sphinx-doc.org/en/master/ext/autodoc.html#directive-automodule -- 你可以搜索“如果方法的签名被装饰器隐藏,这个很有用。”

在我的情况下,我需要使用autofunction来指定我在django应用的tasks.py模块中celery任务的签名:

.. automodule:: django_app.tasks
    :members:
    :undoc-members:
    :show-inheritance:

    .. autofunction:: funct1(user_id)
    .. autofunction:: func2(iterations)
15

为了更详细地解释我的评论:

你有没有试过使用decorator这个包,并在checkStale函数前加上@decorator?我之前在用epydoc处理一个被装饰的函数时也遇到过类似的问题。

正如你在评论中提到的,decorator这个包并不属于标准库的一部分。

你可以尝试使用类似下面的代码(这段代码没有经过测试):

try:
    from decorator import decorator
except ImportError:
    # No decorator package available. Create a no-op "decorator".
    def decorator(f):
        return f

撰写回答