Имена динамических функций Python - PullRequest
9 голосов
/ 25 марта 2009

Я ищу лучший способ вызова функций на основе переменной в Python против использования операторов if / else, как показано ниже. Каждый код состояния имеет соответствующую функцию

if status == 'CONNECT':
    return connect(*args, **kwargs)
elif status == 'RAWFEED':
    return rawfeed(*args, **kwargs)
elif status == 'RAWCONFIG':
    return rawconfig(*args, **kwargs)
elif status == 'TESTFEED':
    return testfeed(*args, **kwargs)
...

Я предполагаю, что это потребует некоторой фабричной функции, но не уверен в синтаксисе

Ответы [ 8 ]

39 голосов
/ 25 марта 2009

Вы можете найти getattr полезными, я думаю

import module
getattr(module, status.lower())(*args, **kwargs)
19 голосов
/ 25 марта 2009

Канонический способ сделать это - использовать словарь для эмуляции switch или if/elif. Здесь вы найдете несколько вопросов по аналогичным проблемам в SO.

Поместите свои функции в словарь с кодами состояния в качестве ключей:

funcs = {
    'CONNECT': connect,
    'RAWFEED': rawfeed,
    'RAWCONFIG' : rawconfig,
    'TESTFEED': testfeed
}
funcs[status](*args, **kwargs)
15 голосов
/ 25 марта 2009

при условии, что эти функции принадлежат некоторому модулю:

import module
return getattr(module, status.lower()).__call__(*args, **kwargs)
5 голосов
/ 25 марта 2009

это выглядит так, что вы можете использовать getattr немного по-другому (на мой взгляд, более элегантно)

import math
getattr(math, 'sin')(1)

или если функция импортируется, как показано ниже

from math import sin

грех теперь находится в пространстве имен, поэтому вы можете вызвать его по

vars()['sin'](1)
4 голосов
/ 25 марта 2009

Некоторое улучшение ответа SilentGhost:

globals()[status.lower()](*args, **kwargs)

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

Хотя это выглядит некрасиво. Я бы использовал решение со словарем.

3 голосов
/ 25 марта 2009

Посмотрите на это: getattra как диспетчер функций

1 голос
/ 25 марта 2009

Я сталкивался с той же проблемой ранее. Посмотрите на этот вопрос, я думаю, это то, что вы ищете.

Словарь или заявления If

Надеюсь, это полезно

Eef

0 голосов
/ 25 марта 2009

небольшое изменение по сравнению с предыдущим:

funcs = {
'CONNECT': connect,
'RAWFEED': rawfeed,
'RAWCONFIG' : rawconfig,
'TESTFEED': testfeed
}

func = funcs.get('status')
if func:
    func(*args, **kwargs)
...