在哪里放置装饰器的文档字符串

Chr*_*ris 5 python docstring decorator python-3.x python-decorators

我正在尝试记录装饰器,但不确定文档字符串应该放在哪里。从技术上讲,它是包含我想要记录的参数的内部包装器,但用户将应用外部函数名称作为装饰器。

例如,

def change_case(func):
    """Does the doc string go here
    """
    def _wrapper(s, case=None):
        """Or, does the doc string go here?
        """
        if case == 'Upper':
            s = s.upper()
        elif case == 'Lower':
            s = s.lower()
        return func(s)

    return _wrapper

@change_case
def echo(s):
    return s

echo('Test', case='Upper')
Run Code Online (Sandbox Code Playgroud)

在上面,文档字符串是否在 change_case() 或 _wrapper() 之后。我倾向于前者。

Chr*_*ean 7

将实际装饰器的文档放在顶级装饰器函数中。当用户尝试使用您的装饰器时,他们希望在这里找到它的文档。例如,functools.singledispatch从标准库中获取装饰器:

>>> from functools import singledispatch
>>>
>>> print(singledispatch.__doc__) # the decorator has it's documentation in the actually decorator function
Single-dispatch generic function decorator.

    Transforms a function into a generic function, which can have different
    behaviours depending upon the type of its first argument. The decorated
    function acts as the default implementation, and additional
    implementations can be registered using the register() attribute of the
    generic function.


>>>
Run Code Online (Sandbox Code Playgroud)

但是,您还应该使用functools.wraps装饰函数中包含的任何文档传输到包装函数:

>>> from functools import wraps
>>>
>>> def dec(func):
...     @wraps(func)
...     def wrap(*args, **kwargs):
...         return func(*args, **kwargs)
...     return wrap
...
>>> @dec
... def func():
...     """Docstring here"""
...
>>> print(func.__doc__)
Docstring here
>>>
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过使用“functools.wraps”作为示例而不是“functools.singledispatch”来使答案更加元:^) (2认同)