• Как сделать так чтобы фраза не повторялась?

    Vindicar
    @Vindicar
    RTFM!
    MrHaska531, тебе нужно понять, что такое время жизни переменной/объекта, и представлять себе процесс выполнения программы.
    get_rept() выполняется с самого начала каждый раз, когда ты вводишь команду /get, и выполняется до конца.
    a - локальная переменная, а потому она создаётся в начале вызова get_rept() и удаляется по завершению выполнения.
    Как следствие, твои условия не имеют смысла, они все будут отрабатывать одно за другим во время обработки одного (!) сообщения /get.
    Если ты хочешь сохранить состояние программы между вызовами get_rept(), тебе придётся созранять данные где-то снаружи get_rept().

    Очень упрощённый пример:
    a = 0  # эта переменная будет создана при запускек бота, и будет жить, пока он работает
    @bot.message_handler(commands=['get'])
    def get_rept(message):
        global a  # мы будем ссылаться на a снаружи функции, в т.ч. перезаписывать её.
        if a == 0:  # пользователь вводит команду первый раз
            ...  # делаем что нужно
            a = 1  # запоминаем
        elif a == 1:  # обрати внимание, мы делаем если-иначе!
            # в противном случае если строка a = 1 отработает, то и это условие тоже отработает
            ...  # пользователь вводит команду второй раз, делаем что нужно
        # ну и так далее


    Проблема этого кода в том, что переменная a - одна на всего бота. А потому бот не будет различать, который пользователь уже ввёл команду, а который ещё нет. После первого же ввода /get команда всегда бдует считать, что она уже была введена (до перезапуска бота).

    Можно модифицировать это так:
    users = {}  # словарь пользователей, вводивших команду
    @bot.message_handler(commands=['get'])
    def get_rept(message):
        global users
        # получаем предыдущее состояние для того пользователя, который ввёл команду
        state = users.get(message.chat.id, 0)  # если пользователь ещё не вводил её, получим 0.
        if state == 0:  # команда введена в первый раз
            ...  # делаем что хотим
            users[message.chat.id] = 1  # обновляем состояние данного пользователя
        # ну и так далее

    Этот подход уже лучше, но он имеет недостаток: наше состояние хранится в оперативной памяти. Бот забудет значение переменной state при перезапуске.
    Значит, нам нужно как-то сохранять state. Мы могли бы:
    а) сохранять state, скажем, в json файл при каждом изменении (и загружать её из файла при запуске бота). Колхозное решение, хотя и простое.
    б) более правильно, освоить работу с простой СУБД, например модуль sqlite3, и сохранять состояние в таблице в базе данных.

    aiogram также имеет механизм register_next_step_handler(). Он позволяет вызывать разные функции в ответ на одно и то же событие (например, сообщение), приходящее несколько раз. Но при этом состояние (т.е. какую функцию вызывать дальше) не сохраняется при перезапуске бота. Т.е. это в чём-то напоминает вариант со словарём.
    Ответ написан
    1 комментарий