Pass ** kwargs argument to another function with ** kwargs

I do not understand the following example, let's say I have the following functions:

# python likes def save(filename, data, **kwargs): fo = openX(filename, "w", **kwargs) # <- #1 fo.write(data) fo.close() # python doesnt like def save2(filename, data, **kwargs): fo = openX(filename, "w", kwargs) # <- #2 fo.write(data) fo.close() def openX(filename, mode, **kwargs): #doing something fancy and returning a file object 

Why is # 1 the correct solution and # 2 the wrong? **kwargs is basically a dict, so if I want to pass an openX argument, I think the correct path would be without ** and just give a dict. But python clearly doesn't like the second one and tells me that I gave 3 instead of 2 arguments. So what is the reason for this?

+118
python
Mar 26 '12 at 6:28
source share
6 answers

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

By prefixing the dictionary "**", you unpack the kwargs dictionary into keyword arguments.

A dictionary (type dict ) is the only variable containing key-value pairs.

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

Any dictionary can be unpacked into the arguments of the keyword, prefix it with ** during a function call.

+124
Mar 26 2018-12-12T00:
source share

Syntax ** tells Python to collect keyword arguments in a dictionary. save2 passes it as an argument without a keyword (a dictionary object). openX does not see any keyword arguments, so **args not used. Instead, it receives a third argument without a keyword (dictionary). To fix this, change the definition of the openX function.

 def openX(filename, mode, kwargs): pass 
+9
Mar 26 '12 at 6:37
source share

Because the dictionary is the only meaning. You need to use the keyword extension if you want to pass it as a group of keyword arguments.

+1
Mar 26 '12 at 6:30
source share

For # 2, args will only be a formal parameter with a dict value, but not a keyword type parameter.

If you want to pass a keyword type parameter to the keyword argument you need to indicate ** in front of your dictionary, which means ** args

check it out for more details on using ** kw

http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/

+1
Mar 26 2018-12-12T00:
source share

Statement to the above:

def model (functions, target): global arguments regularizer = no type regularizer = args.regularizastion_type.lower ...

This is part of the code where we use regularization approaches L1 and L2 to ultimately reduce the re-equipment. I get the error "no module named args" after entering "global args".

0
Nov 19 '18 at 20:53
source share

By expanding on @gecco's answer, below is an example that will 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 dictionary unpacking works, and why sending a real dictionary failed

0
Jun 27 '19 at 12:37
source share



All Articles