Normal arguments vs. keyword arguments

Question:

How are “keyword arguments” different from regular arguments? Can’t all arguments be passed as name=value instead of using positional syntax?

Asked By: mk12

||

Answers:

There are two ways to assign argument values to function parameters, both are used.

  1. By Position. Positional arguments do not have keywords and are assigned first.

  2. By Keyword. Keyword arguments have keywords and are assigned second, after positional arguments.

Note that you have the option to use positional arguments.

If you don’t use positional arguments, then — yes — everything you wrote turns out to be a keyword argument.

When you call a function you make a decision to use position or keyword or a mixture. You can choose to do all keywords if you want. Some of us do not make this choice and use positional arguments.

Answered By: S.Lott

Using keyword arguments is the same thing as normal arguments except order doesn’t matter. For example the two functions calls below are the same:

def foo(bar, baz):
    pass

foo(1, 2)
foo(baz=2, bar=1)
Answered By: Eli Grey

Positional Arguments

They have no keywords before them. The order is important!

func(1,2,3, "foo")

Keyword Arguments

They have keywords in the front. They can be in any order!

func(foo="bar", baz=5, hello=123)

func(baz=5, foo="bar", hello=123)

You should also know that if you use default arguments and neglect to insert the keywords, then the order will then matter!

def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
Answered By: Unknown

I’m surprised no one has mentioned the fact that you can mix positional and keyword arguments to do sneaky things like this using *args and **kwargs (from this site):

def test_var_kwargs(farg, **kwargs):
    print "formal arg:", farg
    for key in kwargs:
        print "another keyword arg: %s: %s" % (key, kwargs[key])

This allows you to use arbitrary keyword arguments that may have keys you don’t want to define upfront.

Answered By: Gabriel Hurley

There is one last language feature where the distinction is important. Consider the following function:

def foo(*positional, **keywords):
    print "Positional:", positional
    print "Keywords:", keywords

The *positional argument will store all of the positional arguments passed to foo(), with no limit to how many you can provide.

>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}

The **keywords argument will store any keyword arguments:

>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}

And of course, you can use both at the same time:

>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}

These features are rarely used, but occasionally they are very useful, and it’s important to know which arguments are positional or keywords.

Answered By: too much php

There are two related concepts, both called “keyword arguments“.

On the calling side, which is what other commenters have mentioned, you have the ability to specify some function arguments by name. You have to mention them after all of the arguments without names (positional arguments), and there must be default values for any parameters which were not mentioned at all.

The other concept is on the function definition side: you can define a function that takes parameters by name — and you don’t even have to specify what those names are. These are pure keyword arguments, and can’t be passed positionally. The syntax is

def my_function(arg1, arg2, **kwargs)

Any keyword arguments you pass into this function will be placed into a dictionary named kwargs. You can examine the keys of this dictionary at run-time, like this:

def my_function(**kwargs):
    print str(kwargs)

my_function(a=12, b="abc")

{'a': 12, 'b': 'abc'}
Answered By: Ian Clelland

I’m surprised that no one seems to have pointed out that one can pass a dictionary of keyed argument parameters, that satisfy the formal parameters, like so.

>>> def func(a='a', b='b', c='c', **kwargs):
...    print 'a:%s, b:%s, c:%s' % (a, b, c)
... 
>>> func()
a:a, b:b, c:c
>>> func(**{'a' : 'z', 'b':'q', 'c':'v'})
a:z, b:q, c:v
>>> 
Answered By: sherman

Using Python 3 you can have both required and non-required keyword arguments:


Optional: (default value defined for param ‘b’)

def func1(a, *, b=42):
    ...
func1(value_for_a) # b is optional and will default to 42

Required (no default value defined for param ‘b’):

def func2(a, *, b):
    ... 
func2(value_for_a, b=21) # b is set to 21 by the function call
func2(value_for_a) # ERROR: missing 1 required keyword-only argument: 'b'`

This can help in cases where you have many similar arguments next to each other especially if they are of the same type, in that case I prefer using named arguments or I create a custom class if arguments belong together.

Answered By: Christophe Roussy

I was looking for an example that had default kwargs using type annotation:

def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
     return ' '.join([a, b, c, str(kwargs)])

example:

>>> print(test_var_kwarg('A', c='okay'))
A B okay {}
>>> d = {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', c='c', b='b', **d))
a b c {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', 'b', 'c'))
a b c {}
Answered By: jmunsch

Just suplement/add a way for defining the default value of arguments that is not assigned in key words when calling the function:

def func(**keywargs):
if 'my_word' not in keywargs:
    word = 'default_msg'
else:
    word = keywargs['my_word']
return word

call this by:

print(func())
print(func(my_word='love'))

you’ll get:

default_msg
love

read more about *args and **kwargs in python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3

Answered By: sonictl