-
-
Notifications
You must be signed in to change notification settings - Fork 2
FSM (Конечные автоматы)
lxstvayne edited this page Nov 20, 2021
·
1 revision
Если вашему боту необходима система диалогов, то в дело вступают конечные автоматы. Это некая математическая модель, которая представляет собой набор конечных состояний, которые переключаются в определённых условиях. В библиотеке это реализовано с помощью классов:
from vk_maria.longpoll.fsm import StatesGroup, State, MemoryStorage, FSMContext
class Form(StatesGroup):
waiting_for_name: State
waiting_for_age: State
waiting_for_gender: State
Необходимо описать в классе переменные состояний.
Чтобы имелась возможность запоминать текущие состояния для диалогов всех пользователей, в класс LongPoll необходимо передать экземпляр хранилища состояний.
lp = LongPoll(vk, MemoryStorage())
Пример работы конечных автоматов:
@lp.message_handler(commands=['/start'])
def cmd_start(event: types.Message):
Form.waiting_for_name.set()
event.reply("Hi there! What's your name?")
@lp.message_handler(state=Form.waiting_for_name)
def process_name(event: types.Message, state: FSMContext):
state.update_data(name=event.message.text)
Form.next()
event.reply("How old are you?")
@lp.message_handler(state=Form.waiting_for_age)
def process_age(event: types.Message, state: FSMContext):
Form.next()
state.update_data(age=event.message.text)
markup = KeyboardMarkup(one_time=True)
markup.add_button(Button.Text(Color.PRIMARY, 'Male'))
markup.add_button(Button.Text(Color.PRIMARY, 'Female'))
markup.add_button(Button.Text(Color.PRIMARY, 'Other'))
event.reply('What is your gender?', keyboard=markup)
@lp.message_handler(state=Form.waiting_for_gender)
def process_gender(event: types.Message, state: FSMContext):
state.update_data(gender=event.message.text)
user_data = state.get_data()
event.answer(f'Hi! Nice to meet you, {user_data["name"]}\n'
f'Age: {user_data["age"]}\n'
f'Gender: {user_data["gender"]}')
Form.finish()
lp.polling()
Чтобы каждый раз не писать
state = FSMContext.get_current()
Можно передавать второй аргумент в функцию обработчик.
@lp.message_handler(state=Form.waiting_for_gender)
def process_gender(event: types.Message, state: FSMContext):
Чтобы отлавливать состояние, передаётся аргумент state
для message_handler
:
@lp.message_handler(state=Form.waiting_for_gender)