Не обнуляется список в функции

При написании Telegram-бота столкнулся с такой проблемой, что динамические данные записываемые в список внутри функции не обнуляются после её выполнения.

Мне нужно, чтобы пользователь выбирал значения через InlineKeyboard и они записывались во в список из которого позже пойдут в базу данных. Но получается так, что, когда один пользователь записал значения в список у другого пользователя они такие же, потому что список, содержащий временные значения не обнулился после выполнения функции.

С данной проблемой я столкнулся впервые и только при написании Telegram-бота. В остальных скриптах на Python все значения переменных в функциях при повторном их запуске принимают исходное значение.

Пример кода:

# Не буду прописывать весь код c начала, просто функция запускается
# после получения любого коллбэка
@bot.callback_query_handler(func=lambda call: True)
def callback_worker(call):
    test_func(call) # запуск функции


def test_func(call):
    user_id = call.from_user.id

    temp_data = [] # список для временных значений


    keyboard = telebot.types.InlineKeyboardMarkup()

    keyboard.row(telebot.types.InlineKeyboardButton('Кнопка 1',
                                      callback_data='button-1'),
                 telebot.types.InlineKeyboardButton('Кнопка 2',
                                      callback_data='button-2'))

    bot.send_message(chat_id=user_id,
                     text='Тестовое сообщения 1',
                     reply_markup=keyboard)

    @bot.callback_query_handler(func=lambda call: call.data.startswith('button'))
    def callback_handler_1(call):
        num_1 = call.data.split('-')[1] # номер находящийся после "button-" 

        temp_data.append(num_1) # запись первого, временного значения


        keyboard = telebot.types.InlineKeyboardMarkup()

        keyboard.row(telebot.types.InlineKeyboardButton('Кнопка 3',
                                                    callback_data='next_button-3'),
                     telebot.types.InlineKeyboardButton('Кнопка 4',
                                                    callback_data='next_button-4'))

        bot.send_message(chat_id=user_id,
                         text='Тестовое сообщения 2',
                         reply_markup=keyboard)

        @bot.callback_query_handler(func=lambda call: call.data.startswith('next_button'))
        def callback_handler_2(call):
            num_2 = call.data.split('-')[1] # номер находящийся после "button-" 

            temp_data.append(num_2) # запись второго, временного значения

            bot.send_message(chat_id=user_id,
                             text=f'{temp_data}')

            # Вывод при первом запуске с нажатием кнопок - 1 и 3: "[1, 3]"
            # Вывод при втором запуске с нажатием кнопок - 2 и 4: "[1, 3, 2, 4]"
            # Вывод при втором запуске с нажатием кнопок - 1 и 4: "[1, 3, 2, 4, 1, 4]"
            # И так далее....

введите сюда описание изображения

Список остаётся с теми же значениями, которые были в него внесены в предшествующих запусках, а не становится снова пустым как прописано в начале функции.

Я конечно думал про написание костыля с использованием temp_data.clear() после выполнения функции, но не думаю, что это было бы правильным решением.

Вот пример такой же функции, но реализованной не для Telegram:

def test_func():
    temp_data = []
    print(temp_data) # вывод списка до дополнения
    temp_data.append(1)
    print(temp_data) # вывод списка после дополнения

test_func() # [] [1]
test_func() # [] [1]
test_func() # [] [1]

В данном примере, всё работает так, как надо, при повторных запусках функции - список обнуляется до исходного состояния.

введите сюда описание изображения

Надеюсь на помощь, заранее спасибо!


Ответы (1 шт):

Автор решения: dudha369

Мне кажеться что проблема может крыться в том что temp_data это не глобальная переменая. Попробуйте использования приведёного снизу кода, где переменая temp_data стаёт глобальной при каждом первом её использовании в новых функциях:

@bot.callback_query_handler(func=lambda call: True)
def callback_worker(call):
    test_func(call) # запуск функции


def test_func(call):
    user_id = call.from_user.id

    temp_data = [] # список для временных значений


    keyboard = telebot.types.InlineKeyboardMarkup()

    keyboard.row(telebot.types.InlineKeyboardButton('Кнопка 1',
                                      callback_data='button-1'),
                 telebot.types.InlineKeyboardButton('Кнопка 2',
                                      callback_data='button-2'))

    bot.send_message(chat_id=user_id,
                     text='Тестовое сообщения 1',
                     reply_markup=keyboard)

    @bot.callback_query_handler(func=lambda call: call.data.startswith('button'))
    def callback_handler_1(call):
        num_1 = call.data.split('-')[1] # номер находящийся после "button-" 

        global temp_data
        temp_data.append(num_1) # запись первого, временного значения


        keyboard = telebot.types.InlineKeyboardMarkup()

        keyboard.row(telebot.types.InlineKeyboardButton('Кнопка 3',
                                                    callback_data='next_button-3'),
                     telebot.types.InlineKeyboardButton('Кнопка 4',
                                                    callback_data='next_button-4'))

        bot.send_message(chat_id=user_id,
                         text='Тестовое сообщения 2',
                         reply_markup=keyboard)

        @bot.callback_query_handler(func=lambda call: call.data.startswith('next_button'))
        def callback_handler_2(call):
            num_2 = call.data.split('-')[1] # номер находящийся после "button-" 

            global temp_data
            temp_data.append(num_2) # запись второго, временного значения

            bot.send_message(chat_id=user_id,
                             text=f'{temp_data}')

Если данный вариант не сработает, попробуйте создавать temp_data ещё до создания всех функций и добавьте строчку global temp_data перед строкой temp_data = [] # список для временных значений в функии test_func. Если столкнётесь с проблемами, пишите в коментарии, я постараюсь Вам помочь!

→ Ссылка