So I am working on some hackerrank questions and someone posted the following snippet of code as part of a solution and I was curious if someone could explain it to me please?
getattr(l, parts[0])(*(map(int, parts[1:])))
In the following thread:
Python using getattr to call function with variable parameters
Mgilson mentioned this can be done for any function/method and I became confused.
In the getattr() documentation I found no information of passing *args after the function and so was confused. Is this method generally applicable to all functions? If so could someone please provide a few basic examples and explain why this is true?
I would greatly appreciate this!
You won't find this in getattr
's documentation because passing
arguments to a function using the *
operator is a totally different
thing.
This code:
l = "my_fun"
getattr(l, parts[0])(*(map(int, parts[1:])))
is actually equivalent to:
l = "my_fun"
fun = getattr(l, parts[0])
fun(*(map(int, parts[1:])))
You get the function called my_fun
, then call this function. map(int, parts[1:])
maps items of parts[1:]
to integers and then the *
operator unpacks these integer to use them as arguments of fun
.
So this solution works as long as the function called has a number of
arguments equal to len(parts[1:])
.
Here is another example with two files.
# my_pack/__init__.py
def fun1(x):
print('x =', x)
def fun2(x, y):
print('x =', x, ', y =', y)
# test.py
import my_pack
args = [1]
fun = getattr(my_pack, 'fun1')
fun(*args)
# equivalent solution
fun = getattr(my_pack, 'fun1')(*args)
args = [1, 2]
fun = getattr(my_pack, 'fun2')(*args)
What @mgilson said is that this principle of calling a function
without listing explicitly all its parameters but using the *
operator is totally independent from getattr
. As for instance here
where I don't use getattr
:
def my_cool_func(a, b, c):
print(a, b, c)
my_cool_func(*[1, 2, 3]) # prints "1 2 3"