Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Passing parameters by name along with kwargs

In python we can do this:

def myFun1(one = '1', two = '2'):     ... 

Then we can call the function and pass the arguments by their name:

myFun1(two = 'two', one = 'one') 

Also, we can do this:

def myFun2(**kwargs):     print kwargs.get('one', 'nothing here')  myFun2(one='one') 

So I was wondering if it is possible to combine both methods like:

def myFun3(name, lname, **other_info):     ...  myFun3(lname='Someone', name='myName', city='cityName', otherInfo='blah') 

In general what combinations can we do?

Thanks and sorry for my silly question.

like image 721
CodeArtist Avatar asked Feb 25 '13 19:02

CodeArtist


People also ask

How do you pass Kwargs in Python?

Kwargs allow you to pass keyword arguments to a function. They are used when you are not sure of the number of keyword arguments that will be passed in the function. Kwargs can be used for unpacking dictionary key, value pairs. This is done using the double asterisk notation ( ** ).

What is the correct way to use the Kwargs statement?

The double asterisk form of **kwargs is used to pass a keyworded, variable-length argument dictionary to a function. Again, the two asterisks ( ** ) are the important element here, as the word kwargs is conventionally used, though not enforced by the language.

What is Kwarg?

The special syntax **kwargs in function definitions in python is used to pass a keyworded, variable-length argument list. We use the name kwargs with the double star. The reason is that the double star allows us to pass through keyword arguments (and any number of them).

How do you pass multiple Kwargs Python?

Python 3.5+ allows passing multiple sets of keyword arguments ("kwargs") to a function within a single call, using the `"**"` syntax.


2 Answers

The general idea is:

def func(arg1, arg2, ..., kwarg1=default, kwarg2=default, ..., *args, **kwargs):     ... 

You can use as many of those as you want. The * and ** will 'soak up' any remaining values not otherwise accounted for.

Positional arguments (provided without defaults) can't be given by keyword, and non-default arguments can't follow default arguments.

Note Python 3 also adds the ability to specify keyword-only arguments by having them after *:

def func(arg1, arg2, *args, kwonlyarg=default):     ... 

You can also use * alone (def func(a1, a2, *, kw=d):) which means that no arguments are captured, but anything after is keyword-only.

So, if you are in 3.x, you could produce the behaviour you want with:

def myFun3(*, name, lname, **other_info):     ... 

Which would allow calling with name and lname as keyword-only.

Note this is an unusual interface, which may be annoying to the user - I would only use it in very specific use cases.

In 2.x, you would need to manually make this by parsing **kwargs.

like image 132
Gareth Latty Avatar answered Oct 04 '22 03:10

Gareth Latty


It's possible at least for Python 2.7. Keyword arguments get assigned to positional parameters by name, so you can do

In [34]: def func(name, lname, **kwargs):     print 'name='+name, 'lname='+lname     print kwargs    ....:       In [35]: func(lname='lname_val', name='name_val', city='cityName', otherInfo='blah') name=name_val lname=lname_val {'city': 'cityName', 'otherInfo': 'blah'} 

Official docs state it that way: "If keyword arguments are present, they are first converted to positional arguments, as follows. First, a list of unfilled slots is created for the formal parameters. If there are N positional arguments, they are placed in the first N slots. Next, for each keyword argument, the identifier is used to determine the corresponding slot (if the identifier is the same as the first formal parameter name, the first slot is used, and so on). If the slot is already filled, a TypeError exception is raised. Otherwise, the value of the argument is placed in the slot, filling it (even if the expression is None, it fills the slot)." https://docs.python.org/2/reference/expressions.html#calls

like image 38
user2745509 Avatar answered Oct 04 '22 03:10

user2745509