2011-03-08 71 views
10

在红宝石,如果我有一个obj对象,用一种称为funcname的,我可以使用下面的语法 obj.send调用方法(funcname的)等效红宝石obj.send在python

是否有类似的东西在python中。

我想这样做,我有,我设置的funcname的一个switch语句,并希望在switch语句结束调用它的原因。

+2

Python中没有按” t有一个switch语句。而且,在运行时生成函数名几乎总是一个坏主意。 – 2011-03-08 21:53:29

+1

@Rafe:这不是通常需要的,但它本身并没有什么坏处。 – 2011-03-08 22:02:01

+0

是的,它不,但我仍然想要和if-elif-else循环。我想我在下面得到了我的答案。 – 2011-03-08 22:02:57

回答

19
getattr(obj, "name")(args) 

9

嗯... GETATTR(OBJ,funcname的)(*指定参数时,** kwargs)?

>>> s = "Abc" 

>>> s.upper() 
'ABC' 

>>> getattr(s, "upper")() 
'ABC' 

>>> getattr(s, "lower")() 
'abc' 
1

除了已经提到的getattr()内置:

作为替代的,如果 - elif的,否则循环,可以使用字典到你的“案件”映射到所需的函数/方法:

# given func_a, func_b and func_default already defined 
function_dict = { 
    'a': func_a, 
    'b': func_b 
} 
x = 'a' 
function_dict(x)() # -> func_a() 
function_dict.get('xyzzy', func_default)() # fallback to -> func_c 

关于方法,而不是简单的功能:

  • 你可以把上面的é xample为method_dict使用例如lambda obj: obj.method_a()而不是function_a等,然后做method_dict[case](obj)
  • 你可以使用getattr()其他答案已经提到过,但你只需要它,如果你真的需要从它的名字的方法。
  • operator.methodcaller()从STDLIB在某些情况下,一个很好的快捷方式:基于一个方法的名称,以及可选的一些参数,它会创建一个叫这个名字的方法在另一个对象的函数(如果你提供的任何额外的参数创建时在methodcaller,它会调用这些参数的方法)
1

或者,如果你愿意的话,operator.methodcaller('foo')是在不管你通过它调用foo的功能。换句话说,

import operator 
fooer = operator.methodcaller("foo") 
fooer(bar) 

相当于

bar.foo() 

(我想这大概是在合适的类别中的共轭或双。如果你爱好数学。)