Задать вопрос
  • Как правильно создать и разделить разные функции под одним хендлером?

    Vindicar
    @Vindicar
    RTFM!
    Читаем документацию и учимся использовать встроенные средства бот-библиотеки.
    @bot.message_handler(func=lambda message: message.text == 'О нас')
    def blabla1(message):
        ...  # тут логика реакции на сообщение "О нас"
    
    @bot.message_handler(func=lambda message: message.text == 'Чем займёмся?')
    def blabla2(message):
        ...  # тут логика реакции на сообщение "Чем займёмся?"
    
    @bot.message_handler(func=lambda message: True)
    def whatever(message):
        ...  # тут логика реакции на все остальные сообщения. Эта функция должна идти строго последней.
    Ответ написан
    Комментировать
  • Как вернуться из модуля обратно в main?

    Vindicar
    @Vindicar
    RTFM!
    Фигню творишь. Отношения между модулями должны быть строго односторонними - один модуль предоставляет сервис, другой его использует. В этом случае просто не будет необходимости в циклическом импорте.

    Если же у тебя более сложная ситуация, придётся выкручиваться. Например: main описывает бота, который используется модулем, который уже предоставляет сервис через этого бота. Тут ситуация усложняется телеботом, который не особенно пригоден для многомодульных ботов. Хотя есть приём, который можно сравнить с внедрением зависимостей.

    module1.py
    # бота передаём как параметр внутрь функции install_module
    # если у тебя будут другие глобальные ресурсы, скажем, соединение с СУБД, можно передавать их также
    def install_module(bot) -> None:  
        # да, мы описываем функцию прямо внутри другой функции. Так можно
        @bot.message_handler(commands=['some_command', ])
        def my_command(message):
            ...  # тут логика команды
    
        # и ещё одну...
        @bot.message_handler(commands=['other_command', ])
        def my_other_command(message):
            ...  # тут логика команды

    Тогда в main.py будет что-то вроде
    import telebot
    bot=telebot.TeleBot('TOKEN')
    # импортируем и активируем модуль
    import module1
    module1.install_module(bot)  # install_module() модуля должна вызываться строго однажды
    # модулей может быть несколько
    import module2
    module2.install_module(bot)
    # когда всё установлено, запускаем бота
    bot.infinity_polling()

    Идею можно развить таким образом: пусть твои модули лежат не рядом с main.py, а в подпапке modules. Тогда можно сделать что-то такое, чтобы автоматически подгрузить все модули из этой папки при старте бота.
    from pathlib import Path
    import sys
    import importlib
    
    import telebot
    
    bot=telebot.TeleBot('TOKEN')
    
    MAIN_DIR = Path(sys.argv[0]).parent.resolve()  # папка где лежит скрипт бота
    MODULES_DIR = MAIN_DIR / 'modules'  # лежащая рядом папка modules
    for item in MODULES_DIR.glob('*'):   # перебираем файлы и папки в папке modules
        # игнорируем папки и файлы, начинающиеся с _ или с .
        if item.name.startswith('_') or item.name.startswith('.'):
            continue
        # item - это имя пригодного для импорта модуля?
        if (item.isfile() and item.name.endswith('.py')) or (item.isdir() and (item / '__init__.py').isfile()):
            # да импортируем и активируем модуль
            module = importlib.import_module('modules.'+item.name)
            module.install_module(bot)
    
    # когда всё установлено, запускаем бота
    bot.infinity_polling()
    Ответ написан
    2 комментария