Как получить ссылку на функцию из класса?

def command(**kwargs):  # Декоратор
    def wrapper(*args):
        return kwargs

    return wrapper


class Aliases:
    @property
    def commands(self) -> tuple:
        return (
            self.new_alias,
        )

    @command(
        command="новый алиас",
        args={"алиас": "str"}
    )
    def new_alias(self, message: types.Message):
        ...

Есть класс Aliases, а в нём функция commands которая возвращает некоторые функции из класса. Если функция new_alias будет без декоратора command, то функция commands возвращает ссылку на функцию (то что мне нужно), но если функция new_alias будет с декоратором command, то функция commands возвращает аргументы декоратора ({'command': 'новый алиас', 'args': {'алиас': 'str'}}), без ссылки на функцию. Как я могу получить таким образом ссылку на функцию и аргументы из декоратора command?


Ответы (1 шт):

Автор решения: Chorkov

Ссылка передаваемая во врапер внутри декоратора, это и есть ссылка на функцию, которую вы собираетесь декорировать. К сожалению, в вашей реализации декоратора эта информация навсегда потеряна.

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

def command(**kwargs):  # Декоратор
    def wrapper(func_ref):
        func_ref.command_kwargs = kwargs
        return func_ref
    return wrapper

class Aliases:
    @property
    def commands(self) -> tuple:
        return (
            self.new_alias.command_kwargs,
        )
    @command(
        command="новый алиас",
        args={"алиас": "str"}
    )
    def new_alias(self, message: types.Message):
       ...

Кроме того, для целей самодокументирования кода посмотрите в сторону docstring:

https://pypi.org/project/docstring-parser/

https://peps.python.org/pep-0257/

→ Ссылка