pythonnamedtuple

define the args of a function outside the actual call


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.


Solution

  • 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"])