让狮身人面像识别正确的签名

the*_*oom 13 python decorator python-sphinx

我一直在努力获取我的文档,以便我正在开发一个包含镜像客户端和服务器API的开源项目.为此,我创建了一个装饰器,大部分时间都可以用来记录一个简单地对其输入执行验证的方法.你可以找到一个完整的类这些方法在这里和装饰的实现在这里.

正如您所见,装饰器functools.wraps用于保存文档字符串,我也认为是签名,但源代码与生成的文档如下所示:

资源:源代码

VS

文档: 狮身人面像文档

有谁知道有任何方法让setH生成的文档显示正确的呼叫签名?(没有为每个签名设置一个新的装饰器 - 我需要镜像的方法)

我找到了一个解决方法,其中涉及让装饰器不更改未绑定的方法,但让类在绑定时改变方法(对象实例化) - 这看起来像是一个黑客,所以任何评论,或其他方式的做法这,将不胜感激.

bbo*_*boe 5

PRAW中,我通过使用条件装饰器来处理这个问题,条件装饰器在 sphinx 构建发生时返回原始函数(而不是装饰后的函数)。

在 PRAW 的 sphinx conf.py 中,我添加了以下内容来确定 SPHINX 当前是否正在构建:

import os
os.environ['SPHINX_BUILD'] = '1'
Run Code Online (Sandbox Code Playgroud)

然后在 PRAW 中,它的装饰器如下所示:

import os

# Don't decorate functions when building the documentation
IS_SPHINX_BUILD = bool(os.getenv('SPHINX_BUILD'))

def limit_chars(function):
    """Truncate the string returned from a function and return the result."""
    @wraps(function)
    def wrapped(self, *args, **kwargs):
        output_string = function(self, *args, **kwargs)
        if len(output_string) > MAX_CHARS:
            output_string = output_string[:MAX_CHARS - 3] + '...'
        return output_string
    return function if IS_SPHINX_BUILD else wrapped
Run Code Online (Sandbox Code Playgroud)

return function if IS_SPHINX_BUILD else wrapped行允许 SPHINX 获取正确的签名。

相关来源


And*_*ier 2

为了扩展我对伊森答案的简短评论,这是我使用该functools包的原始代码:


import functools

def trace(f):
    """The trace decorator."""
    logger = ... # some code to determine the right logger
    where = ... # some code to create a string describing where we are

    @functools.wraps(f)
    def _trace(*args, **kwargs):
        logger.debug("Entering %s", where)
        result = f(*args, **kwargs)
        logger.debug("Leaving %s", where)
        return result

    return _trace
Run Code Online (Sandbox Code Playgroud)

这里是使用该包的代码decorator


import decorator

def trace(f):
    """The trace decorator."""
    logger = ... # some code to determine the right logger
    where = ... # some code to create a string describing where we are

    def _trace(f, *args, **kwargs):
        logger.debug("Entering %s", where)
        result = f(*args, **kwargs)
        logger.debug("Leaving %s", where)
        return result

    return decorator.decorate(f, _trace)
Run Code Online (Sandbox Code Playgroud)

出于性能原因,我们希望将代码移出实际函数包装器以确定正确的记录器和位置字符串。因此,在两个版本中都采用了嵌套包装函数的方法。

两个版本的代码都适用于 Python 2 和 Python 3,但第二个版本在使用 Sphinx 和 autodoc 时为修饰函数创建正确的原型(无需在 autodoc 语句中重复原型,如本答案中所建议的

这是使用 cPython,我没有尝试 Jython 等。