Динамически вызываемые функции - Python - PullRequest
5 голосов
/ 12 мая 2010

У меня есть список функций ... например,

def filter_bunnies(pets): ...

def filter_turtles(pets): ...

def filter_narwhals(pets): ...

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

, например

'filter_bunnies', 'filter_turtles', 'filter_narwhals'

Ответы [ 8 ]

9 голосов
/ 12 мая 2010

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

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

>>> getattr(A(), 'filter_bunnies')(1)
bunnies
4 голосов
/ 12 мая 2010

Да, вы можете использовать:

globals()['filter_bunnies']()

для вызова filter_bunnies.

2 голосов
/ 12 мая 2010

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

2 голосов
/ 12 мая 2010

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

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')
0 голосов
/ 12 мая 2010

Обычно, когда мне нужно отправить вызов функции одной из нескольких функций, основанных на строке, я сделаю функции элементами 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 голосов
/ 12 мая 2010

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

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

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

0 голосов
/ 12 мая 2010

См. Функцию eval.

0 голосов
/ 12 мая 2010

с использованием eval ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...