Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of ruby obj.send in python

Tags:

python

send

In ruby if I have an object obj, with a method called funcname, I can call the method using the following syntax obj.send(funcname)

Is there something similar in python.

The reason I want to do this, that I have a switch statement where I set the funcname, and want to call it at the end of the switch statement.

like image 683
Puneet Paul Avatar asked Mar 08 '11 21:03

Puneet Paul


3 Answers

getattr(obj, "name")(args)

​​​​

like image 199
Glenn Maynard Avatar answered Sep 20 '22 01:09

Glenn Maynard


hmmm... getattr(obj, funcname)(*args, **kwargs) ?

>>> s = "Abc"

>>> s.upper()
'ABC'

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

>>> getattr(s, "lower")()
'abc'
like image 10
Georges Martin Avatar answered Sep 19 '22 01:09

Georges Martin


Apart from the already mentioned getattr() builtin:

As an alternative to an if-elif-else loop you can use a dictionary to map your "cases" to the desired functions/methods:

# 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

Concerning methods instead of plain functions:

  • you can just turn the above example into method_dict using for example lambda obj: obj.method_a() instead of function_a etc., and then do method_dict[case](obj)
  • you can use getattr() as other answers have already mentioned, but you only need it if you really need to get the method from its name.
  • operator.methodcaller() from the stdlib is a nice shortcut in some cases: based on a method name, and optionally some arguments, it creates a function that calls the method with that name on another object (and if you provided any extra arguments when creating the methodcaller, it will call the method with these arguments)
like image 1
Steven Avatar answered Sep 22 '22 01:09

Steven