quadboii
@quadboii

Как ипортировать функции из файлов?

У меня есть два файла, в первом это
#main
import telebot
import config

# инициализация
bot = telebot.TeleBot(config.Token)

Во втором это
import telebot
from telebot import types
import config

bot = telebot.TeleBot(config.Token)
    
@bot.message_handler(commands=['start'])
def start(message):
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    btn0 = types.KeyboardButton(' Каталог фильмов')
    btn1 = types.KeyboardButton(" Каталог фильмов")
    btn2 = types.KeyboardButton(' Случайный фильм')
    btn3 = types.KeyboardButton(' Предложить фильм')
    markup.add(btn0, btn1, btn2, btn3)
    bot.send_message(message.from_user.id, ' Привет, {0.first_name}. Я Kinomorph - бот, с которым ты можешь найти интересный фильм для просмотра вечером\n \n Если у тебя есть номер или название фильма, ввести его можно прямо сейчас'.format(message.from_user), reply_markup=markup)

Нужно импортировать и запустить в первом файле функцию из второго
  • Вопрос задан
  • 453 просмотра
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
Ещё один товарищ не учил Питон, но рвётся написать божественного бота...

Когда ты импортируешь файл (модуль), этот модуль выполняется - практически так же, как если бы ты его запустил непосредственно. Различие есть, но небольшое. Теперь посмотрим на твои файлы.
В первом файле ты объявляешь переменную bot. Она существует в пространстве имён первого файла (модуля).
Если ты в нём делаешь import second_file, в нём тоже присутствует создание переменной bot - в локальном пространстве имён этого модуля. Это две разные переменные, и два разных экземпляра класса Telebot.
Поэтому когда ты выполняешь в одном файле bot.run() (ну или как там бот запускается), ты запускаешь только один экземпляр. Второй остаётся неактивированным, и всё, что к нему привязано, не работает.

Тебе надо как-то передать переменную bot во-второй файл, не нарвавшись при этом на циклический импорт (чтобы не было "первый импортирует второй, а второй - первый").
Тут поможет ещё один простой факт: в питоне всё - операторы. Т.е. объявление функции - это оператор. Его можно помещать куда угодно, внутрь любого блока программы: внутрь if, внутрь цикла, внутрь другой функции. Он выполнится при выполнении соответствующего блока.
Так что ты можешь завернуть свои обработчики из второго файла в функцию, принимающую ссылку на bot. А потом импортировать эту внешнюю функцию в первый файл и там её вызвать.
#второй файл, second_file.py
import telebot
from telebot import types
# эта функция создаст все обработчики и зарегистрирует их в предоставленном боте
# вызывай её строго один раз за скрипт
def register_handlers(bot):
    # а тут уже пошли обработчики
    @bot.message_handler(commands=['start'])
    def start(message):
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
        btn0 = types.KeyboardButton(' Каталог фильмов')
        btn1 = types.KeyboardButton(" Каталог фильмов")
        btn2 = types.KeyboardButton(' Случайный фильм')
        btn3 = types.KeyboardButton(' Предложить фильм')
        markup.add(btn0, btn1, btn2, btn3)
        bot.send_message(message.from_user.id, ' Привет, {0.first_name}. Я Kinomorph - бот, с которым ты можешь найти интересный фильм для просмотра вечером\n \n Если у тебя есть номер или название фильма, ввести его можно прямо сейчас'.format(message.from_user), reply_markup=markup)

# любой код, который не должен исполняться при импорте, оформляй так:
if __name__ == '__main__':   # переменная __name__ содержит имя, под которым импортируется модуль
    print('Этот код выполнится ТОЛЬКО если файл запущен напрямую.')
    print('Он не выполнится при импорте файла.')


# первый файл, main.py
import telebot
import config
import second_file  # модуль импортируется - в нём __name__ будет равно "second_file", а не "__main__"

# инициализация
bot = telebot.TeleBot(config.Token)
second_file.register_handlers(bot)  # тут вызывается импортированная функция
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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