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

Почему при исполнении импортированого кода исполняется код из другого импорта?

Есть файл start.py в котором при исполнении условий if, elif, elif, elіf и т.д. исполняются разные функции которые прописанны там же или в импортированых файлах. Например, есть два файла userAdd.py и userDelete.py которые выполняют функцию добавления и удаления соответсвенно в базе данных MySQL.

Файл userAdd.py:
def handle_adm_btn1(bot, message):
    keyboard = types.InlineKeyboardMarkup()
    keyboard.add(table_btn1, table_btn2)
    keyboard.add(table_btn3, table_btn4)
    keyboard.add(table_btn5, table_btn6)
    keyboard.add(table_btn7, table_btn8)
    keyboard.add(table_btn9, table_btn10)
    keyboard.add(table_btn11)
    # Отправляем сообщение с запросом выбора таблицы
    bot.send_message(message.chat.id, text39, reply_markup=keyboard)
    @bot.callback_query_handler(func=lambda call: True)
    def chekCallData(call):
        allowed_data = (calldata1, calldata2, calldata3, calldata4, calldata5, calldata6, calldata7, calldata8, calldata9, calldata10, calldata11)
        table_name = call.data
        handle_table_selection(bot, message, table_name)

def handle_table_selection(bot, message, table_name):
    # Отправляем сообщение с запросом ввода номера
    bot.send_message(message.chat.id, text40)
    # Устанавливаем состояние пользователя в ожидание ввода номера
    bot.register_next_step_handler(message, lambda msg: handle_number_input(bot, msg, table_name))
    print("Некст степ хандлер input вызван")

def handle_number_input(bot, message, table_name):
    print("Функция number_input пошла")
    number = message.text
    cursor = mydb.cursor()
    sql_query = f"INSERT INTO {table_name} (phone_number, is_try) VALUES (%s, %s)"
    values = (number, 1)
    cursor.execute(sql_query, values)
    mydb.commit()
    cursor.close()
    bot.send_message(message.chat.id, text41)
    bot.clear_step_handler_by_chat_id(message.chat.id)
    print("clear_step_handler_by_chat_id")


Файл userDelete.py:
def handle_adm_btn2(bot, message):
    keyboard = types.InlineKeyboardMarkup()
    keyboard.add(table_btn1, table_btn2)
    keyboard.add(table_btn3, table_btn4)
    keyboard.add(table_btn5, table_btn6)
    keyboard.add(table_btn7, table_btn8)
    keyboard.add(table_btn9, table_btn10)
    keyboard.add(table_btn11)
    # Отправляем сообщение с запросом выбора таблицы
    bot.send_message(message.chat.id, text44, reply_markup=keyboard)
    @bot.callback_query_handler(func=lambda call: True)
    def chekCallData2(call):
        allowed_data = (calldata1, calldata2, calldata3, calldata4, calldata5, calldata6, calldata7, calldata8, calldata9, calldata10, calldata11)
        table_name = call.data
        handle_table_selection2(bot, message, table_name)

def handle_table_selection2(bot, message, table_name):
    # Отправляем сообщение с запросом ввода номера
    bot.send_message(message.chat.id, text40)
    # Устанавливаем состояние пользователя в ожидание ввода номера
    bot.register_next_step_handler(message, lambda msg: handle_number_input2(bot, msg, table_name))
    print("Некст степ хандлер input2 вызван")

def handle_number_input2(bot, message, table_name):
    print("Функция number_input2 пошла")
    number = message.text
    cursor = mydb.cursor()
    sql_query = f"DELETE FROM {table_name} WHERE phone_number = %s"
    values = (number,)
    cursor.execute(sql_query, values)
    mydb.commit()
    cursor.close()
    bot.send_message(message.chat.id, text45)
    bot.clear_step_handler_by_chat_id(message.chat.id)
    print("clear_step_handler_by_chat_id")


При условии, если вызываю сначала первым handle_adm_btn1, то принты выводятся такие:
handle_adm_btn1 вызвана
handle_table_selection вызвана
Некст степ хандлер input вызван
Функция number_input вызвана
clear_step_handler_by_chat_id


Если после этого вызываю handle_adm_btn2, то принты уже выводятся вот такие:
handle_adm_btn2 вызвана
handle_table_selection вызвана
Некст степ хандлер input вызван
Функция number_input вызвана
clear_step_handler_by_chat_id


То есть, handle_adm_btn2 вызывает функцию handle_table_selection, а не handle_table_selection2. Изза этого весь дальнейший код идёт по первому сценарию.

В обратном порядке(если сначала вызвать handle_adm_btn2, а потом handle_adm_btn1) тоже так работает. Почему? Ведь вызов функции прописан верно.
  • Вопрос задан
  • 127 просмотров
Подписаться 2 Простой Комментировать
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
xx_RuBiCoN_xx, ну потому что надо не просто копипастить код, а документацию изучать, чтобы понимать, за что отвечает каждая часть твоего кода.
@bot.callback_query_handler(func=lambda call: True)

Параметр func должен содержать ссылку на функцию-фильтр, которая определит, должен ли данный обработчик вызываться для данного callback query. При этом вызовется первый подходящий обработчик, т.е. первый обработчик, у котого фильтр вернёт True.
У тебя везде понатыкано lambda call: True, т.е. "для любого query вызывать этот обработчик". Как следствие, первый объявленный "универсальный" обработчик вызывается всегда и для всего. На имя функции боту наплевать.

Самый простой способ разделить код на два обработчика - убедиться, что call.data имеет хорошо различимые значения. Например, добавить префикс: у кнопок для одного обработчика call.data пусть всегда начинается с "btn1.", а у другого с "btn2.". Тогда можно будет написать функцию-фильтр вида lambda call: call.data.startswith('btn1.') и т.п.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
SoreMix
@SoreMix
yellow
@bot.callback_query_handler(func=lambda call: True)
def chekCallData(call):

и
@bot.callback_query_handler(func=lambda call: True)
def chekCallData2(call):


Имеют одинаковые декораторы. Если в коде несколько одинаковых декораторов, вызывается тот, который был объявлен первым
Ответ написан
Ваш ответ на вопрос

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

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