pass **kwargs argument to another function with **kwargs

The ** syntax tells Python to collect keyword arguments into a dictionary. The save2 is passing it down as a non-keyword argument (a dictionary object). The openX is not seeing any keyword arguments so the **args doesn't get used. It's instead getting a third non-keyword argument (the dictionary). To fix that change the definition of the openX function.

def openX(filename, mode, kwargs):
    pass

In the second example you provide 3 arguments: filename, mode and a dictionary (kwargs). But Python expects: 2 formal arguments plus keyword arguments.

By prefixing the dictionary by '**' you unpack the dictionary kwargs to keywords arguments.

A dictionary (type dict) is a single variable containing key-value pairs.

"Keyword arguments" are key-value method-parameters.

Any dictionary can by unpacked to keyword arguments by prefixing it with ** during function call.


Expanding on @gecco 's answer, the following is an example that'll show you the difference:

def foo(**kwargs):
    for entry in kwargs.items():
        print("Key: {}, value: {}".format(entry[0], entry[1]))

# call using normal keys:
foo(a=1, b=2, c=3)
# call using an unpacked dictionary:
foo(**{"a": 1, "b":2, "c":3})

# call using a dictionary fails because the function will think you are
# giving it a positional argument
foo({"a": 1, "b": 2, "c": 3})
# this yields the same error as any other positional argument
foo(3)
foo("string")

Here you can see how unpacking a dictionary works, and why sending an actual dictionary fails

Tags:

Python