动态方法调用在Python 2.7中使用方法名称的字符串

Dynamic Method Call In Python 2.7 using strings of method names

我有一个tuple,它列出了类的方法,比如:

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

等等……

现在,我需要根据用户所做的选择动态调用这些方法。将根据索引调用这些方法。因此,如果用户选择"0",则调用methA;如果选择"5",则调用methF

我的方法如下:

1
2
3
4
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

如果需要调用当前模块中的函数

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

其中args是要发送的参数列表或元组,或者您可以像在其他任何函数中那样在调用中列出它们。因为您在一个方法中试图对同一对象调用另一个方法,所以请使用第一个方法和self替换obj

getattr获取一个对象和一个字符串,并在对象中查找属性,如果该属性存在,则返回该属性。obj.xgetattr(obj, 'x')达到了同样的效果。如果您想进一步研究这种反射,还可以使用setattrhasattrdelattr函数。

< BR>完全替代的方法:
在注意到这个答案得到的关注程度之后,我将建议对你正在做的事情采取不同的方法。我假设有一些方法

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

为了使每个方法对应一个数字(选择),我构建了一个字典,将数字映射到方法本身。

1
2
3
4
5
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)。在你真正的代码中,考虑到上面的内容,你可能会得到

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