@MrHaska531

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

Вот код:

@bot.message_handler(commands=['get'])
def get_rept(message):
	a=0
	if message.text=='/get':
		a+=1
		bot.send_message(message.chat.id,"Выберете рептилию:")
		if message.text=='/get' and a>=2:
			bot.send_message(message.chat.id, 'Простите, но у вас уже есть рептилие.')

Нужно сделать так, чтобы когда вводил команду /get два раз он вывод фразу 'Простите, но у вас уже есть рептилие.' . А если один раз то "Выберете рептилию:".
Если вы не разбираетесь в модуле pyTelegramBotAPI, то вот упрощенная версия:

a=input()
b=0
if a=='Привет':
    a+=1
    print('Привет!')
    if a==2:
        print('Простите, но мы уже здоровались')
  • Вопрос задан
  • 89 просмотров
Решения вопроса 1
Vindicar
@Vindicar
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(). Он позволяет вызывать разные функции в ответ на одно и то же событие (например, сообщение), приходящее несколько раз. Но при этом состояние (т.е. какую функцию вызывать дальше) не сохраняется при перезапуске бота. Т.е. это в чём-то напоминает вариант со словарём.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы