Остановка и продолжение работы функции через время
Разрабатываю телеграмм бота (вообще не очень важно, что это для бота, так как вопрос относится только к Python'у), а точнее улучшенную библиотеку для него, что бы облегчить написание дальнейшего кода.
Многие спрашивают, а как сделать так, что бы посреди функции можно было ожидать отправки пользователем нового сообщения, но единственное, что на такое отвечают, это делать несколько функций и через машину состояний их вызывать.
Я так и делал. Но потом узнал об модуле inspect и мне пришёл в голову такой код (отправка сообщений и их получение из тг заменены на print() и input()):
import inspect
import re
def start_bot(message):
print(f'You sent me: {message}')
print('Hello! What is your name?')
#wait_for_message
print(f'{message}, I am your new friend.')
def convert(func):
code = inspect.getsource(func)
name = func.__name__
code = re.sub(rf'def {name}.+?\n', '', code)
code = re.sub(r'^\s\s', '', code, flags = re.M)
funcs = list()
for func in code.split('\n#wait_for_message\n'):
funcs.append(func)
return funcs
converted_func = convert(start_bot)
count = 0
while True:
message = input()
exec(converted_func[count])
count += 1
Функция convert() в этом скрипте, конвертирует функцию start_bot() на несколько функций, которые потом можно вызвать. Таким образом, я не создаю две функции start_bot() и get_name(), а только одну.
Мне интересно, насколько этот способ хорош и стоит ли использовать такой метод, а также, если он не очень плох, то можно ли как-то разделённую функцию хранить более безопасным способом, а не как набор строк?
Ответы (1 шт):
Кажется вы пытаетесь повторно изобрести сопрограммы
def start_bot():
name = yield "What's your name?"
have_pet = yield f'Hello, {name}. Do you have a pet?'
if have_pet.lower() in ['y', 'yes']:
pet_name = yield "What's his name?"
def run(coro):
try:
print('<bot>', coro.send(None))
while True:
print('<bot>', coro.send(input('<you> ')))
except StopIteration:
pass
run(start_bot())