Остановка и продолжение работы функции через время

Разрабатываю телеграмм бота (вообще не очень важно, что это для бота, так как вопрос относится только к 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 шт):

Автор решения: extrn

Кажется вы пытаетесь повторно изобрести сопрограммы

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())
→ Ссылка