@ZERRITO
Пустой ноль

Есть ли коги или что-то им подобное в Telegram?

Раньше работал с телеграм ботами, но писал всё в один файл, так как код был не слишком громоздким. Потом перешёл в Дискорд, где я делал ботов покрупнее, и я узнал у когах, с помощью которых можно разделять бота на части и раскидывать эти самые части по файлам. Дело в том, что в отличии от telebot, в discord.py такая функция присутствует, и мне стало интересно, есть ли коги (или можно ли их сделать) для телеграм ботов? (Я понимаю что сделать можно всё, но мне интересен сам способ) Ведь крупные боты как-то работают, и я очень сомневаюсь, что их пихают в один файл.
  • Вопрос задан
  • 257 просмотров
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Можно сделать самому.
Смотри, ключевая возможность в большинстве библиотек для ботов - это регистрация реакции бота на события. И чаще всего она выполняется декоратором, типа @bot.command в discord.py или его эквивалент в aiogram.
Но что такое декоратор? Если он не имеет параметров, то тогда
@some_decorator
def some_func():
    pass

это то же самое, что и
def some_func():
    pass
some_func = some_decorator(some_func)

Для декораторов с параметрами чуть-чуть сложнее
@some_decorator(params)
def some_func():
    pass

превратится в
def some_func():
    pass
wrapper = some_decorator(params)
some_func = wrapper(some_func)

Отсюда вывод. Декоратор - это функция, и его можно сохранять в переменные, вызывать и так далее.
Тогда можно сделать такой трюк: написать декоратор-прокси, который запоминает, что за метод мы декорируем, и чем. Примерно так:
def proxy(storage, *args, **kwargs):
    def wrapper(func):
        storage.append((func.__name__, args, kwargs))
        return func
    return wrapper

И применять его примерно так:
class MyCustomCog:
    methods = []
    def __init__(self, bot):
        #задача конструктора - прочитать список отмеченных методов класса, 
        #и отдекорировать методы своего экземпляра класса (не одно и то же)
        for fn, args, kwargs in self.methods:
            #а тут вызываем декоратор вручную
            #что там вместо bot.event? можно сделать несколько прокси, или добавить еще один параметр
            decorator = bot.event(*args, **kwargs) 
            decorator(getattr(self, fn)) #теперь бот знает про наши обработчики событий
    #декоратор-прокси запоминает все декорированые методы в список methods
    #это можно реализовать и по другому, не суть. Главное, что мы запоминаем,
    #с какими параметрами потом вызывать декоратор реального бота - всё, что после methods
    @proxy(methods, "параметры", for="декоратора бота")
    async def some_handler(self, params):
        pass #обработчик того или иного события

Эту логику можно спрятать в базовый класс, и наследоваться от него, чтоб не повторяться по сто раз. Да и сам proxy() можно сделать методом этого базового класса.
Ответ написан
Ваш ответ на вопрос

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

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