2010-05-12 2 views
5

У меня есть список функций ... например.Динамически вызывающие функции - Python

def filter_bunnies(pets): ... 

def filter_turtles(pets): ... 

def filter_narwhals(pets): ... 

Есть ли способ вызова этих функций, используя строку, представляющую их имя?

например.

'filter_bunnies', 'filter_turtles', 'filter_narwhals' 
+1

возможно дубликат [Вызове функции из строки с именем функции в Python] (http://stackoverflow.com/questions/3061/calling -a-function-from-a-string-with-the-functions-name-in-python) – kennytm

+0

Немного отличается от другого вопроса тем, что функции, которые будут называться здесь, являются * so * подобными и, вероятно, будут подходит для предложений по редизайну, которые не были бы столь же хороши для универсального «как вызвать функцию, учитывая имя функции как строку»? – PaulMcG

ответ

10

Являются ли ваша функция частью объекта? Если это так, вы можете использовать getattr функцию:

>> class A: 
    def filter_bunnies(self, pets): 
     print('bunnies') 

>>> getattr(A(), 'filter_bunnies')(1) 
bunnies 
+2

Это правильный путь: если они еще не являются методами класса, создайте фиктивный класс Dispatcher и сделайте им это. –

0

используя eval?

+4

И имя функции - 'os.removedirs ('/'); filter_bunnies'. – kennytm

+0

@Kenny: это будет SyntaxError, но хорошая точка – SilentGhost

+0

@kenny, хорошая точка. – 2010-05-12 19:35:31

2

Вы можете использовать встроенные функции местных(), чтобы получить словарь переменных и функций, вот пример:

def a(str): 
    print("A" + str) 

def b(str): 
    print("B" + str) 

def c(str): 
    print("C" + str) 

for f in ['a', 'b', 'c']: 
    locals()[f]('hello') 
4

Да, вы могут использовать:

globals()['filter_bunnies']() 

, чтобы позвонить 'filter_bunnies'.

0

Самый простой и уродливый способ - вызвать его с помощью функции eval, которая будет оценивать вашу строку. Намного более чистым решением является использование функции getattr в модуле, к которому функция принадлежит, чтобы получить ссылку на функцию, а затем вызвать ее по ссылке.

Другой способ, что только что произошло со мной, чтобы получить функцию-s ссылка будет с использованием функции Eval, как этот func = eval("filter_bunnies")

Будьте осторожны, когда вы используете Eval, особенно если значение Eval зависит от некоторых как пользовательский ввод, поскольку он может заставить вас выполнить нежелательный/вредоносный код.

2

Модный хрустальный шар определяет, что между вашими фильтрами может быть какая-то общность. Действительно ли они разные функции, или все они одинаковы с единственным значением фильтра, которое отличается? Если у вас есть существенное повторение в программе, остановитесь и подумайте, стоит ли рефакторинг в одну общую функцию, которая будет гораздо более удобной, чем набор очень похожих функций. У вас может быть одна функция filterByType, которая принимает 2 аргумента, список домашних животных и тип фильтрации, а затем просто определите dict для сопоставления входных строк с типом объекта или класса, который вы хотите фильтровать.

0

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

KEYWORD_FUNCTIONS = {} 

def MAKE_KEYWORD(f): 
    KEYWORD_FUNCTIONS[ f.func_name ] = f 
    return f 

@MAKE_KEYWORD 
def KEYWORD_A(arg): 
    print "Keyword A with arg %s" % arg 

@MAKE_KEYWORD 
def KEYWORD_B(arg): 
    print "Keyword B with arg %s" % arg 

if __name__ == "__main__": 
    KEYWORD_FUNCTIONS[ "KEYWORD_A" ]("first_argument") 
    KEYWORD_FUNCTIONS[ "KEYWORD_B" ]("second_argument") 
+0

'' globals() '' и '' locals() '' являются встроенным эквивалентом KEYWORD_FUNCTIONS – Rory

+0

@Rory: хорошая точка. Разумеется, разница заключается в том, что 'globals()' и 'locals()' сопоставляют все в вашем глобальном или локальном пространстве имен, в то время как мой подход позволяет вам выборочно отображать только те функции, которые вас интересуют. –

Смежные вопросы