Задать вопрос
@FOUREX

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

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?
  • Вопрос задан
  • 413 просмотров
Подписаться 2 Средний 7 комментариев
Решения вопроса 1
@FOUREX Автор вопроса
def command(**kwargs):
    def wrapper(func_ref):
        func_ref.command_kwargs = kwargs
        return func_ref

    return wrapper


class Aliases:
    def __init__(self, bot: Bot):
        self.bot = bot

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

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


def setup(bot: Bot, dp: Dispatcher):
    aliases = Aliases(bot)

    for function in aliases.commands:
        print(function, function.command_kwargs)


Вывод в консоль:

<\bound method Aliases.new_alias of <\aliases.py.Aliases object at 0x7f4b0d0c2560>> {'name': 'новый алиас', 'args': {'алиас': 'str'}}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Redeve
Веб-макаке не хватит и 640гБ
осторожно
from functools import wraps, partial

def command(**cmdargs):
    def _run(func):
        @wraps(func)
        def wrapper(self, *args):
            return partial(func, self, args, cmdargs)
        return wrapper
    return _run

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

    @command(
        command="новый алиас",
        args={"алиас": "str"}
    )
    def new_alias(self, *args):
        for arg in args:
            if isinstance(arg, str):  # заменить на types.Message):
                return arg
        return args


>>> aliases = Aliases()
>>> aliases.commands
(functools.partial(<function Aliases.new_alias at 0x778154c550>, <__main__.Aliases object at 0x778205af50>, (), {'command': 'новый алиас', 'args': {'алиас': 'str'}}),)
>>> aliases.commands[0]
functools.partial(<function Aliases.new_alias at 0x778154c550>, <__main__.Aliases object at 0x778205af50>, (), {'command': 'новый алиас', 'args': {'алиас': 'str'}})
>>> aliases.commands[0].args[2]
{'command': 'новый алиас', 'args': {'алиас': 'str'}}
>>> aliases.commands[0]("types.Message object")
'types.Message object'
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы