@kephir

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

В общем я пишу телеграм бота на питон с помощью библиотеки aiogram, она асинхронная и мне впринципе хорошо жилось с глобальными переменными ровно до того момента, пока ботом не стали пользоваться несколько человек сразу... т.к. пошарил в интернете понял что глобальные переменные обновляются каждый раз у сех пользователей. Я нашел, что в синхронных функциях можно возвращать значения переменных с помощью return, но вот незадача - у меня асинхронная библиотека... Если я пытаюсь исплользовать return то код дальше становится недоступным (further code is unreachable), а await то ли впринципе не возвращает то ли только не int, в общем - непонятно... Посоветуйте, что с этой бедой делать?
Код:
@dp.callback_query_handler(lambda c: c.data == 'Hetry')
async def process_callback_button1(callback_query: aiogram.types.CallbackQuery):

    global a
    global b
    global theme
    global fotofinder
    global rightans
    global rightansfoto
    global fotopick

    if a == 1:
        fotopick = random.randint(1, 3)
        with open(f'tgbot/{theme}/{a}/{a}lvl/{fotopick}.jpg', 'rb') as photo:
            fotofinder = photo.read()
        with open(f'tgbot/{theme}/{a}/{a}lvlans/{fotopick}.txt', 'r', encoding='utf-8') as file:
            rightans = file.read()
        with open(f'tgbot/{theme}/{a}/{a}lvlansfoto/{fotopick}.jpg', 'rb') as photo:
            rightansfoto = photo.read()

    elif a == 2:
        fotopick = random.randint(1, 3)
        with open(f'tgbot/{theme}/{a}/{a}lvl/{fotopick}.jpg', 'rb') as photo:
            fotofinder = photo.read()
        with open(f'tgbot/{theme}/{a}/{a}lvlans/{fotopick}.txt', 'r', encoding='utf-8') as file:
            rightans = file.read()
        with open(f'tgbot/{theme}/{a}/{a}lvlansfoto/{fotopick}.jpg', 'rb') as photo:
            rightansfoto = photo.read()

    elif a == 3:
        fotopick = random.randint(1, 3)
        with open(f'tgbot/{theme}/{a}/{a}lvl/{fotopick}.jpg', 'rb') as photo:
            fotofinder = photo.read()
        with open(f'tgbot/{theme}/{a}/{a}lvlans/{fotopick}.txt', 'r', encoding='utf-8') as file:
            rightans = file.read()
        with open(f'tgbot/{theme}/{a}/{a}lvlansfoto/{fotopick}.jpg', 'rb') as photo:
            rightansfoto = photo.read()

    await bot.answer_callback_query(callback_query.id)
    await bot.send_photo(callback_query.from_user.id, photo=fotofinder, caption='Вот ваше животное. Оно вам понравилась?')

    @dp.message_handler(lambda message: message.text and message.text.lower() == rightans)
    async def text_handler(message: aiogram.types.Message):

        global buttons3
        global keyboard3

        buttons3 = [
            aiogram.types.InlineKeyboardButton(text="Следующая задача", callback_data='Hetry'),
            aiogram.types.InlineKeyboardButton(text="Выбрать другой уровень сложности", callback_data='OtherGrade'),
            aiogram.types.InlineKeyboardButton(text="Выбрать другое животное", callback_data='OtherTheme')
        ]
        keyboard3 = aiogram.types.InlineKeyboardMarkup(row_width=1, one_time_keyboard=False).add(*buttons3)

        global b
        b = True

        await message.reply(text=f'Да, это правильный ответ, молодец!', reply_markup=keyboard3)

    @dp.message_handler(lambda message: message.text and message.text.lower() != rightans and b)
    async def text_handler(message: aiogram.types.Message):

        global b
        b = False

        await message.reply(text=f'Неправильно, попробуй еще раз.')

    @dp.message_handler(lambda message: message.text and message.text.lower() != rightans and not b)
    async def text_handler(message: aiogram.types.Message):

        global b
        b = True

        await bot.send_photo(chat_id=user_id, photo=rightansfoto,
                             caption='Неправильно, на картинке есть решение и верный ответ. '
                             'Разбери и продолжай тренироваться.', reply_markup=keyboard3)


@dp.callback_query_handler(lambda c: c.data == 'OtherGrade')
async def process_callback_button1(callback_query: aiogram.types.CallbackQuery):
    await bot.answer_callback_query(callback_query.id)
    await bot.send_message(callback_query.from_user.id, 'Выберите уровень сложности', reply_markup=keyboard2)


@dp.callback_query_handler(lambda c: c.data == 'OtherTheme')
async def process_callback_button1(callback_query: aiogram.types.CallbackQuery):
    await bot.answer_callback_query(callback_query.id)
    await bot.send_message(callback_query.from_user.id, 'Выберите животное', reply_markup=keyboard1)


while True:
    aiogram.executor.start_polling(dp, skip_updates=True)
  • Вопрос задан
  • 488 просмотров
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Потому что у каждого пользователя должен быть свой экземпляр хранимых данных.
Например, вместо одиночного хранилища нужно иметь хранилище вида "ключ-значение", где ключом будет ID пользователя, а значением - данные, которые для этого пользователя актуальны.
Природа этого хранилища не принципиальна: может быть простой словарь (если не нужно сохранение состоятния между перезапусками бота), может быть БД, может быть ещё что.

Собственно, в аиограме есть механизм Finite State Machine, который как раз про организацию сценариев, с отслеживанием того, на каком этапе находится конкретный пользователь.

Но для его использования нужно знать питон на уровне немножечко повыше "Если я пытаюсь исплользовать return то код дальше становится недоступным".
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
10 мая 2024, в 03:40
1500 руб./за проект
10 мая 2024, в 03:02
5000 руб./за проект
10 мая 2024, в 02:29
300 руб./за проект