Puneet Paul
Puneet Paul

Reputation: 131

Equivalent of ruby obj.send in python

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.

Upvotes: 13

Views: 4308

Answers (4)

Katriel
Katriel

Reputation: 123662

Or, if you prefer, operator.methodcaller('foo') is a function which calls foo on whatever you pass it. In other words,

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

is equivalent to

bar.foo()

(I think this is probably the adjoint or dual in a suitable category. If you're mathematically inclined.)

Upvotes: 1

Steven
Steven

Reputation: 28666

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)

Upvotes: 1

Georges Martin
Georges Martin

Reputation: 1208

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

>>> s = "Abc"

>>> s.upper()
'ABC'

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

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

Upvotes: 10

Glenn Maynard
Glenn Maynard

Reputation: 57494

getattr(obj, "name")(args)

​​​​

Upvotes: 26

Related Questions