15

我有一个元组,其中列出了类的方法,例如:

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但它会产生错误并且一点也不优雅。

4

1 回答 1

36

如果您在对象(包括导入的模块)上调用方法,您可以使用:

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)

whereargs是要发送的参数列表或元组,或者您可以像在任何其他函数中一样在调用中列出它们。由于您在一个方法中试图在同一个对象上调用另一个方法,因此请使用第一个 withself代替obj

getattr接受一个对象和一个字符串,并在对象中进行属性查找,如果存在则返回该属性。 obj.xgetattr(obj, 'x')达到相同的结果。如果您想进一步研究这种反射,还有setattrhasattr和函数。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
于 2013-07-18T21:59:17.900 回答