Как бы я запустил функцию, учитывая ее имя?

#python

Вопрос:

У меня есть большое количество функций смешивания:

 mix(a, b)
add(a, b)
sub(a, b)
xor(a, b)
...
 

Все эти функции принимают одни и те же входы и обеспечивают разные выходы, все одного типа.
Однако я не знаю, какая функция должна быть запущена до выполнения.

Как бы я реализовал это поведение?

Пример кода:

 def add(a, b):
    return a   b

def mix(a, b):
    return a * b

# Required blend -> decided by other code
blend_name = "add"
a = input("Some input")
b = input("Some other input")

result = run(add, a, b)  # I need a run function
 

Я посмотрел в Интернете, но большинство поисков приводят либо к запуску функций из консоли, либо к тому, как определить функцию.

Комментарии:

1. Вы бы создали словарь, значения которого являются функциями, а имена-ключами. Затем вы ищете функцию по ее имени и вызываете полученный результат

Ответ №1:

Я не очень большой поклонник использования словаря в этом случае, поэтому вот мой подход getattr . хотя технически это почти то же самое, и принцип тоже почти тот же, код выглядит чище, по крайней мере, для меня

 class operators():
    def add(self, a, b):
        return (a   b)

    def mix(self, a, b):
        return(a * b)


# Required blend -> decided by other code
blend_name = "add"
a = input("Some input")
b = input("Some other input")
method = getattr(operators, blend_name)
result = method(operators, a, b)
print(result) #prints 12 for input 1 and 2 for obvious reasons
 

Редактировать
это отредактированный код без getattr него, и он выглядит намного чище. таким образом, вы можете сделать этот класс модулем и импортировать по мере необходимости, также легко добавлять новые операторы, не заботясь о добавлении оператора в двух местах (в случае использования словаря для хранения функций в виде ключа/значения).

 class operators():

    def add(self, a, b):
        return (a   b)

    def mix(self, a, b):
        return(a * b)

    def calculate(self, blend_name, a, b):
        return(operators.__dict__[blend_name](self, a, b))


# Required blend -> decided by other code
oper = operators()
blend_name = "add"
a = input("Some input")
b = input("Some other input")
result = oper.calculate(blend_name, a, b)
print(result)
 

Комментарии:

1. также существует функция под названием eval , но я не думаю, что кто-то достаточно уверен, чтобы использовать ее. хотя с его помощью вы бы просто написали result = eval(blend_name f"({a},{b})")

Ответ №2:

Вы можете создать словарь, который сопоставляет имена функций с их функциональными объектами, и использовать его для их вызова. Например:

 functions = {"add": add, "sub": sub}   # and so on
func = functions[blend_name]
result = func(a, b)
 

Или немного более компактным, но, возможно, менее читабельным:

 result = functions[blend_name](a, b)
 

Ответ №3:

Вы можете использовать словарь globals() для модуля.

 result = globals()[blend_name](a, b)
 

Было бы разумно добавить некоторую проверку значений blend_name

Комментарии:

1. Имя смеси проверяется в другом месте, но не было показано, так как я не думал, что это будет частью минимального примера