0

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!

1 Answers1

1

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"
qouify
  • 3,698
  • 2
  • 15
  • 26