使用方法名称字符串在 Python 2.7 中进行动态方法调用 [英] Dynamic Method Call In Python 2.7 using strings of method names

查看:32
本文介绍了使用方法名称字符串在 Python 2.7 中进行动态方法调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

等等..

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

我这样做的方法如下:

def makeSelection(self, selected):#methodname = t[已选择]#但由于这是来自类内部,因此必须附加'self.'methodname# 这里还需要传入一些本地计算的参数

我已经设法用 eval 解决了一些问题,但它会产生错误并且一点也不优雅.

解决方案

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

getattr(obj, method_name)(*args) # 对于这个问题:使用 t[i],而不是 method_name

例如:

<预><代码>>>>s = '你好'>>>getattr(s, 'replace')('l', 'y')'嘿,你'

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

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

其中 args 是要发送的参数列表或元组,或者您可以像处理任何其他函数一样在调用中列出它们.由于您在一个方法中尝试调用同一对象上的另一个方法,请使用带有 self 的第一个方法代替 obj

getattr 接受一个对象和一个字符串,并执行一个属性在对象中查找,如果存在则返回该属性.obj.xgetattr(obj, 'x') 获得相同的结果.如果您想进一步了解这种反射,还有 setattrhasattrdelattr 函数.

<小时>


完全替代的方法:
在注意到这个答案受到了大量关注后,我将建议采用不同的方法来处理您正在做的事情.我假设存在一些方法

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

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

id_to_method = {0:甲基,1:甲基乙,2:甲基丙酸,}

鉴于此,id_to_method[0]() 将调用 methA.它分为两部分,首先是 id_to_method[0] 从字典中获取函数对象,然后 () 调用它.我也可以传递参数 id_to_method[0]("whatever", "args", "I", "want)在您的实际代码中,鉴于上述内容,您可能会遇到类似

choice = int(raw_input('请选择'))id_to_method[choice](arg1, arg2, arg3) # 或者没有参数,随便你

I have a tuple which lists down the methods of a class like:

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

and so on..

Now I need to dynamically call these methods based on a user made selection. The methods are to be called based on the index. So if a user selects '0', methA is called, if '5', methF is called.

My method for doing this is as follows:

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

I have managed to work out something with eval but it yields error and is not at all elegant.

解决方案

If you're calling a method on an object (including imported modules) you can use:

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

for example:

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

If you need to call a function in the current module

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

where args is a list or tuple of arguments to send, or you can just list them out in the call as you would any other function. Since you are in a method trying to call another method on that same object, use the first one with self in place of obj

getattr takes an object and a string, and does an attribute lookup in the object, returning the attribute if it exists. obj.x and getattr(obj, 'x') achieve the same result. There are also the setattr, hasattr, and delattr functions if you want to look further into this kind of reflection.



A completely alternative approach:
After noticing the amount of attention this answer has received, I am going to suggest a different approach to what you're doing. I'll assume some methods exist

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

To make each method correspond to a number (selection) I build a dictionary mapping numbers to the methods themselves

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

Given this, id_to_method[0]() would invoke methA. It's two parts, first is id_to_method[0] which gets the function object from the dictionary, then the () calls it. I could also pass argument id_to_method[0]("whatever", "args", "I", "want) In your real code, given the above you would probably have something like

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

这篇关于使用方法名称字符串在 Python 2.7 中进行动态方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆