0

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.

9
  • 1
    Does this answer your question?
    – Zachiah
    Commented Nov 1, 2023 at 15:24
  • @Zachiah That doesn't help with the args being strings, not values.
    – Barmar
    Commented Nov 1, 2023 at 15:27
  • Yes, it helps. So I need to do something like this: ` functions_to_call = {'fcname1': {'method': 'fc1', 'args': {'var1': var1}}, 'fcname2': {'method': 'fc2', 'args':{'var2':var2, 'var3':var3})}} And to define the variables before the dictionary Commented Nov 1, 2023 at 15:28
  • 1
    BTW, ('var1') needs a comma to make it a tuple: ('var1',)
    – Barmar
    Commented Nov 1, 2023 at 15:28
  • 1
    That still won't work if you assign the dictionary before you assign the variables.
    – Barmar
    Commented Nov 1, 2023 at 15:29

1 Answer 1

0

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.