Динамический метод вызова в Python 2.7 с использованием строк имен методов

У меня есть кортеж, в котором перечислены методы класса, например:

t = ('methA','methB','methC','methD','methE','methF')

и т.д.

Теперь мне нужно динамически вызывать эти методы на основе пользовательского выбора. Методы должны быть вызваны на основе индекса. Поэтому, если пользователь выбирает "0", вызывается methA, если вызывается "5", methF.

Мой метод для этого заключается в следующем:

def makeSelection(self, selected):
    #methodname = t[selected]
    #but as this is from  within the class , it has to be appended with 'self.'methodname
    # also need to pass some arguments locally calculated here

Мне удалось что-то выработать с помощью eval, но оно дает ошибку и совсем не изящно.

Ответ 1

Если вы вызываете метод объекта (включая импортированные модули), вы можете использовать:

getattr(obj, method_name)(*args) #  for this question: use t[i], not method_name

например:

>>> s = 'hello'
>>> getattr(s, 'replace')('l', 'y')
'heyyo'

Если вам нужно вызвать функцию в текущем модуле

getattr(sys.modules[__name__], method_name)(*args)

где args - это список или кортеж аргументов для отправки, или вы можете просто перечислить их в вызове, как и любую другую функцию. Поскольку вы находитесь в методе, пытающемся вызвать другой метод для того же объекта, используйте первый с self вместо obj

getattr принимает объект и строку и выполняет поиск атрибута в объекте, возвращая атрибут, если он существует. obj.x и getattr(obj, 'x') достигают одного и того же результата. Есть также функции setattr, hasattr и delattr, если вы хотите подробнее изучить этот вид отражения.



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

def methA(*args): print 'hello from methA'
def methB(*args): print 'bonjour de methB'
def methC(*args): print 'hola de methC'

Чтобы каждый метод соответствовал номеру (выделение), я строю словарь, отображающий числа в самих методах

id_to_method = {
    0: methA,
    1: methB,
    2: methC,
}

Учитывая это, id_to_method[0]() будет вызывать methA. Он состоит из двух частей: сначала id_to_method[0], который получает объект функции из словаря, затем () вызывает его. Я мог бы также передать аргумент id_to_method[0]("whatever", "args", "I", "want) В вашем реальном коде, учитывая вышеизложенное, вы, вероятно, имели бы что-то вроде

choice = int(raw_input('Please make a selection'))
id_to_method[choice](arg1, arg2, arg3) # or maybe no arguments, whatever you want