Как вызывать функцию, имея строку?
Пишу бота на python-telegram-bot, хочу, чтобы данные для вывода сообщений после нажатия пользователем кнопок брались из базы данных. Не могу понять как правильно вставлять параметр reply_markup в метод send_message. В зависимости от нажатой кнопки, циклом проверяю есть ли такая кнопка в словаре кнопок, передаю key в базу данных и получаю нужную клавиатуру. Без поднятия данных из БД метод выглядит так:
context.bot.send_message(
chat_id=chat_id,
text=text,
reply_markup=get_instruction(),
)
Из БД получаю строку get_instruction(), и при постановке в параметр, конечно же, выполняется с ошибкой. Получилось сделать только вот таким образом:
def do_echo(update: Update, context: CallbackContext):
chat_id = update.message.chat_id
text = update.message.text
for k, value in TITLES.items():
if text in value:
key = k
data = db.get_text_buttons(key)
print(data)
markup = db.get_markup_buttons(key) # Получаем по ключу данные из БД
markup2 = get_bd_parameters(markup)
context.bot.send_message(
chat_id=chat_id,
text=data,
parse_mode=ParseMode.MARKDOWN,
reply_markup=markup2,
)
def get_bd_parameters(markup):
if markup == "get_instruction()":
return get_instruction()
Но для каждой кнопки нужно будет в функции создавать проверку типа if parameter == "parameter": return get_keyboard()
Есть ли способы лаконично оформить этот код без кучи if'ов? Или есть ли способы вызывать функцию, имея строку?
Ответы (1 шт):
Вижу два решения, первое, создать словарь с ключом в виде строки и значением вызываемой функции
def func1():
print("func1")
def func2():
print("func2")
funcs = {
"func1": func1, # функция не вызывается
"func2": func2,
}
markup = "func2"
funcs[markup]() # обратите внимание что вызов функции происходит именно тут
Вывод:
func2
Но, я бы предпочел в этом случае подумать и сделать ключи и хранение в базе более понятными для чтения вашего кода
Второй вариант использовать exec
def func():
print("Hello world")
exec("func()")
Вывод:
Hello world