There is a function def f(x,y,z=False):... There is an attribute of class j, which is a tuple and contains several elements, one nested inside. For example, j = ((f, (x,y)), (fb, (x,y))) . When calling a function in code like this

 for elem in myclass.j: elem[0](elem[1]) 

throws a TypeError error: f () missing 1 required positional argument: 'y'. In fact, I called f ((x, y)). I do not understand how to make it work.

    2 answers 2

    The error says that you have not transferred enough arguments to the function, iterate over two elements and specify the indices for all arguments exactly:

     def f(x, y): return x+y for f, args in ((f, (1, 2)), (f, (3, 5))): print(f(args[0], args[1])) # 3 # 8 

    You can also use unpacking - in python * . The key advantage that gives * is the ability to decompress sequences of unknown length. Suppose in your task functions take different sets of arguments:

     def f(x, y): return x + y def fb(x, y, z): return x + y + z def fbt(a, b, c, x, y, z): return a + b + c + x + y + z j = ((f, (1, 2)), (fb, (1, 2, 3)), (fbt, (1, 2, 3, 4, 5, 6))) for func, args in j: print(func, args) print(func(*args)) # <function f at 0x7fef6fe41bf8> 1 2 # 3 # <function fb at 0x7fef6fe41c80> 1 2 3 # 6 # <function fbt at 0x7fef6fe41d08> 1 2 3 4 5 6 # 21 

    If the arguments are not formed in a tuple, then the following syntax can be used:

     k = ((f, 1, 2), (fb, 1, 2, 3), (fbt, 1, 2, 3, 4, 5, 6)) for func, *args in k: print(func, *args) print(func(*args)) 

      Like that:

       $ python Python 3.7.0 (default, Jul 15 2018, 10:44:58) [GCC 8.1.1 20180531] on linux Type "help", "copyright", "credits" or "license" for more information. >>> def f(x, y): ... print(x + y) ... >>> args = 40, 2 >>> f(*args) 42 >>> j = ((f, (1, 2)), (f, (7, 7))) >>> for i in j: ... i[0](*i[1]) ... 3 14 

      And there is the following syntax:

       >>> def g(**kwargs): ... for key in kwargs: ... print(key, "->", kwargs[key]) ... >>> args = {'a': 1, 'b': 2} >>> g(**args) a -> 1 b -> 2