0

I wondering if it is possible to pass functions with different number of arguments to another function in Python.

For example

def aux_1(arg1,arg2):
    if arg1 > arg2: return 1
    else: return 0
def aux_2(arg1,arg2,arg3):
    return arg1 + arg2 * arg3
def Main_fn(function_to_use,arg1, arg2, arg3):
    return function_to_use(?)
>>>Main_fn(aux_1,1,2,1) #Example cases
>>>Main_fn(aux_2,1,2,1)

So this is my doubt, if I pass function aux_1 how could I ensure it uses only arg1 and arg2. Similarly, if I use aux_2 all the three arguments need to used.

I know it is possible to use a set of if conditions in the Main_fn, using inspect.getargspec()/varargs to appropriately pass on the arguments. However, such a logic would require modifications to the Main_fn each time I make a new aux function to handle its arguments, which is not practical in a large development scenario.

Hence, I'm looking for a way around this.

Please feel free to question me, if in need of further clarifications.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Sakthi K
  • 169
  • 2
  • 15
  • 1
    Not sure that is a duplicate. This question is about whether there is a way to decide how many arguments to pass when *calling* the function, not about whether there's a way to define a function that accepts varargs. The question is unclear though. How would you, the OP, as a human, make that decision without using some sort of "if statement" (i.e., a choice based on which function is being used)? It may be easier just to define the functions to accept varargs, if that is possible. – BrenBarn Sep 14 '14 at 21:42
  • @BrenBarn: the OP is asking how to determine what function to call based on the number of arguments `Main_fn()` received. Which is exactly what the other question answered. – Martijn Pieters Sep 14 '14 at 21:48
  • 1
    @BrenBarn: So I still stand by my opinion that this is best answered with [Python: Can a variable number of arguments be passed to a function?](http://stackoverflow.com/q/919680) – Martijn Pieters Sep 14 '14 at 21:49
  • 1
    It may help if you could tell us why you think you need this capability. It's possible, but it sounds like you may be better off solving a different problem (see: XY problem) – nneonneo Sep 14 '14 at 22:09
  • BrenBarn is right! I'm not looking to pass variable number of arguments nor function overloading. aux_1 and aux_2 are entirely different functions with different functionalities. So, when I want to use aux_1, I need to pass only two arguments. Of course it is possible to use inspect.getargspec/varargs. In which case, I need to remember about every function I create. However, it would be easy if I need not remember all the details...! – Sakthi K Sep 16 '14 at 13:06
  • BrenBarn is the only one who is right!!! Passing variable number of arguments is not my question. I could easily do that with getargspec or varargs. However, this would subsequently require modification to the main function each time an aux_* function is added. I'm trying to do away this... Does any one have any idea?! – Sakthi K Sep 16 '14 at 13:15
  • "However, such a logic would require modifications to the Main_fn each time I make a new aux function" **Why**? Just figure out how many arguments to use (by using `inspect.getargspec`), extract that many arguments (by using `*args` to *receive* the parameters, and slicing that list), and call the function (by using `*` to unpack the arguments that will be passed). There is no conditional logic in that process, and all of these topics are covered by common duplicates. – Karl Knechtel Sep 18 '22 at 14:11
  • I fixed the duplicates list to reflect this, and ensure that up-to-date canonicals are used. – Karl Knechtel Sep 18 '22 at 14:14

2 Answers2

1

Yes, you can use inspect.getargspec to figure out how many arguments a function was defined to take:

import inspect
def get_num_args(f):
    return len(inspect.getargspec(f)[0])

Therefore, you may use get_num_args to decide how many arguments to send in:

if get_num_args(function_to_use) == 2:
    function_to_use(arg1, arg2)
else:
    function_to_use(arg1, arg2, arg3)
nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • I thought about this but this is not what I'm looking for. Consider, I have an optimization problem then the aux_1 and aux_2 would cost functions with different parameters and functionalities. Then this would mean remembering the details of all the functions called by the main function. Of course, i also could varargs. But I'm wondering if there is a "cooler" solution...! – Sakthi K Sep 16 '14 at 13:10
0

Its possible but first when you want to return a function you must be aware that how you invoke the main function ! see this example:

>>> def a():
...  print 3
... 
>>> def b(func):
...  return func
... 
>>> print b(a)
<function a at 0x7feb48e30de8>
>>> b(a())
3

and when you want to use args on inner function when you pass your function to main func you must pass your arguments not when you define the main func ... so you must change this

def Main_fn(function_to_use,arg1, arg2, arg3):
    return function_to_use(?)

to this:

def Main_fn(function_to_use,arg1, arg2, arg3):
    return function_to_use
    #Also note that when you pass arg1, arg2, arg3 in func you must pass them when you invoke the function , if you dont need them you must not pass them in define        

an example :

>>> def a(i,j):
...  print i+j
... 
>>> def b(func):
...  return func
... 
>>> b(a(3,5))
8
>>> 
Mazdak
  • 105,000
  • 18
  • 159
  • 188