I'm using getattr to call different functions depending on a variable.
Im doing something like that:
getattr(foo, bar) ()
That works, calling functions like foo.bar()
My problem is that I have 'bar' functions and I want to call it with different parameters. For example:
def f1() :
pass
def f2(param1) :
pass
def f3(param1,param2) :
pass
so 'bar' could be f1, f2, or f3
I tried this:
assumming that params is a list which contains all parameters needed for the 'bar' function
getattr(foo, bar) (for p in params :)
I watching for a "clean" solution, with no needed to watch the length on the params variable
You could try something like:
getattr(foo, bar)(*params)
This works if params
is a list or a tuple. The elements from params
will be unpacked in order:
params=(1, 2)
foo(*params)
is equivalent to:
params=(1, 2)
foo(params[0], params[1])
If there are keyword arguments, you can do that too.
getattr(foo, bar)(*params, **keyword_params)
where keyword_params
is a dictionary.
Also, This answer is really independent of getattr
. It will work for any function/method.
This is very simple in Python 3. Here is the example:
class C:
def __init__(self, name, age):
self.name = name
self.age = age
def m(self, x):
print(f"{self.name} called with param '{x}'")
return
ci = C("Joe", 10)
print(C)
print(ci)
print(C.m)
print(ci.m)
print(getattr(ci,'m'))
getattr(ci,'m')('arg')
<class '__main__.C'>
<__main__.C object at 0x000001AF4025FF28>
<function C.m at 0x000001AF40272598>
<bound method C.m of <__main__.C object at 0x000001AF4025FF28>>
<bound method C.m of <__main__.C object at 0x000001AF4025FF28>>
Joe called with param 'arg'
Note that getattr is from the builtins module, takes in our case the two parameters, the class instance ci
and the string representing the name of the function.
We could also define the defult value for the parameter.
def m(self, x=None):
print(f"{self.name} caled with param '{x}'")
return
In which case we may call:
getattr(ci,'m')()
A maybe more readable way, which is better for handling exceptions:
class foo:
def method_xy(self, *args, **kwargs):
print(f'args:{args}, kwargs:{kwargs}')
bar = 'method_xy'
xi = foo()
try:
func_name = getattr(xi, bar)
except AttributeError:
# handle missing method
pass
args = ['bla1', 'bla2']
kwargs = {'a1': 1, 'a2': 2}
try:
result = func_name(*args, **kwargs)
except TypeError:
# handle Problems with arguments
pass