Сохранение строк документации функций при их декорировании с использованием классов декораторов - PullRequest
0 голосов
/ 24 февраля 2020

Интересно, как правильно написать класс декоратора, чтобы он сохранил строку документации декорированной функции. Например, рассмотрим следующие строки кода:

import functools

class _vectorize:
    """ (private) decorator to vectorize a function """


    def __init__(self, func):
        functools.update_wrapper(self, func)
        self._func = func

    def __call__(self, values, *args, **kwargs):

        return [self._func(val, *args, **kwargs) for val in values]


@_vectorize
def multiply(v, s):
    """ Multiplies all values in `v` by scalar `s`. """
    return v*s

Мне бы хотелось, чтобы клиент видел строку документации функции multiply, вызывая help(multiply), но это не так:

>>> help(multiply)

Help on instance of _vectorize in module docstring:

multiply = class _vectorize
 |  (private) decorator to vectorize a function
 |  
 |  Methods defined here:
 |  
 |  __call__(self, values, *args, **kwargs)
 |  
 |  __init__(self, func)

Чтобы увидеть правильную документацию, нужно напрямую напечатать атрибут __doc__:

>>> print(multiply.__doc__)
 Multiplies all values in `v` by scalar `s`. 

Как мне изменить декоратор, чтобы help печатал необходимую документацию?

1 Ответ

0 голосов
/ 24 февраля 2020

Я использую functools.wraps, который короче и работает в вашем случае и отображает правильную строку документации:

import functools

def _vectorize(func):
        @functools.wraps(func)
        def wrapFunc(values, *args, **kwargs):
                return [func(val, *args, **kwargs) for val in values]
        return wrapFunc

@_vectorize
def multiply(v, s):
    """ Multiplies all values in `v` by scalar `s`. """
    return v*s

См .: Что делает functools.wraps?

...