define the args of a function outside the actual call

52 Views Asked by At

I have a function that has to call other functions, with a not-fixed number and type of arguments, that I want to set in a dictionary.

Something like this:

def main_function(list_of_subfunctions_to_call):

    functions_to_call = {'fcname1': {'method': 'fc1', 'args': ('var1')}, 
                         'fcname2': {'method': 'fc2', 'args':('var2', 'var3')}}

    var1 = None
    var2 = None
    var3 = None

    for fc in list_of_subfunctions_to_call:
        functions_to_call[fc]['method'](fc['args'])

Of course this doesn't work because the args are strings and not actual variables.

I guess the solution may be related with named tuples but I can't figure out exactly how.

Also, I'm not sure whether this is a good practice, or there is a better way to achieve this same result.

1

There are 1 best solutions below

0
Klops On BEST ANSWER

Being close to your code, this might already be your solution. However, I would suggest to actually name the arguments and use kwargs (key word arguments), as provided in the second code snippet.


def fun1(arg1):
    print(arg1)

def fun2(arg2, arg3):
    print(arg2, arg3)

var1 = "hello"
var2 = "world"
var3 = "!"

functions_to_call = {'fcname1': {'method': fun1, 'args': (var1,)}, 'fcname2': {'method': fun2, 'args':(var2, var3)}}


for fc in functions_to_call.keys():
    print("executing ", fc)
    functions_to_call[fc]['method'](*functions_to_call[fc]["args"])

Note, here the args are passed as dictionaries and unpacked using the ** notation, which provides them as key (argument name) value pairs to the function. This way, it is not important any more to ensure the correct order of the arguments.

def fun1(arg1):
    print(arg1)

def fun2(arg2, arg3):
    print(arg2, arg3)

var1 = "hello"
var2 = "world"
var3 = "!"

functions_to_call = {
    'fcname1': {
        'method': fun1, 'args': {"arg1": var1}
    },
    'fcname2': {
        'method': fun2, 'args': {"arg2": var2, "arg3": var3}
    }
}


for fc in functions_to_call.keys():
    print("executing ", fc)
    functions_to_call[fc]['method'](**functions_to_call[fc]["args"])