330

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

codeforester
  • 39,467
  • 16
  • 112
  • 140
mk12
  • 25,873
  • 32
  • 98
  • 137
  • 6
    You might also want to read PEP 3102 -- they're tidying up some of this stuff in Python 3. See: http://www.python.org/dev/peps/pep-3102/ – Ben Hoyt Sep 14 '09 at 01:28
  • And whether or not there is a default value has nothing to do with it (except whether or not you need pass a value for it), right? – mk12 Sep 14 '09 at 02:06
  • 2
    @Ben Hoyt Added an answer below covering Python 3, required keyword arguments – Christophe Roussy Apr 06 '16 at 09:24

10 Answers10

396

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'}
informatik01
  • 16,038
  • 10
  • 74
  • 104
Ian Clelland
  • 43,011
  • 8
  • 86
  • 87
  • 6
    +1 and accepted: You're the only one who talked about both types of positional+keyword arguments, everyone else either thought I was talking about the first or the second (but they were still good posts). Thanks! – mk12 Sep 14 '09 at 02:02
  • 47
    The wording is unclear: Normally you speak of arguments on the calling side while of parameters on the called side. – glglgl Oct 14 '12 at 07:13
  • 3
    Does the parameter name has to be `kwargs` or I can rename it to sth. like `options` (`def my_fuction(arg1, arg2, **options)`)? – Bruce Sun Sep 01 '18 at 03:13
  • 4
    The name can be anything, though `kwargs` is the convention when there isn't a more appropriate name – Matt Zimmerman Dec 17 '18 at 18:39
  • 2
    I think the second concept explained here is technically called as Arbitrary Keyword Arguments. – Anshul Dahiya Dec 03 '19 at 06:16
  • And per @Eli Grey below, you can apparently also call it using just names and completely ignore the positions of the 'positional' arguments ie. ```my_function(x='kw-x', y='kw-y', arg2='pos-a2', arg1='pos-a1')``` – Ed Randall Jun 15 '21 at 08:12
214

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.

too much php
  • 88,666
  • 34
  • 128
  • 138
  • 4
    Excellent answer! Just a note that required positional arguments can be passed before `*positional`and `**keywords` if we change function definition like `def foo(arg1, *positional, **keywords):`. Here `arg1` is positional and required. Please note that positional in answer means optional and variable number of positional arguments. – shaffooo Dec 25 '17 at 18:54
  • 2
    Yes fine answer. Another note: If you call your function `foo(bar=True)` you can get the values using `bar = keywords.pop('bar')` same as `bar = keywords.pop('bar', None)`. For default value, use `bar = keywords.pop('bar', False)` – oHo Oct 22 '18 at 10:10
127

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)
Eli Grey
  • 35,104
  • 14
  • 75
  • 93
  • 7
    Thanks for this. It's incredibly useful that I can **both** specify a keyword arg as a positional arg, **and** a positional arg as a keyword arg. – Luke Davis Apr 20 '17 at 18:09
  • 1
    Note: This is not possible with Positional-Only Parameters (introduced in PEP 570 accepted in Python 3.8). `pow` with signature as `pow(x, y, z=None, /)` has positional-only parameters (the `/` in the parameter list indicates that all preceding parameters are positional-only. With this change, `pow(x=5, y=3)` causes `Traceback (most recent call last): File "", line 1, in TypeError: pow() takes no keyword arguments`. See https://www.python.org/dev/peps/pep-0570/ – joseville Nov 02 '21 at 17:44
51

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)
Ram Rachum
  • 84,019
  • 84
  • 236
  • 374
Unknown
  • 45,913
  • 27
  • 138
  • 182
  • 9
    IMHO, the 3rd example (default arguments) is not clear. I think you are talking about what happens when one or more parameters declare default values, and the call uses positional notation, but supplies LESS than the number of declared parameters. However, your example has 3 declared, and 3 in the call, so the default values have no effect at all! Did you intend to omit the 3rd arg. e.g. `func("bar", 5)`? And then say that `hello` gets its default value of `3`. – ToolmakerSteve Dec 16 '13 at 20:57
27

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.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 1
    Ohh, I was thinking that of parameters, when what it actually is is the arguments (what *I* pass). Thanks! – mk12 Sep 14 '09 at 01:54
25

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
>>> 
sherman
  • 261
  • 3
  • 3
  • 11
    +1 for a useful technique. Your point would be clearer, without `, **kwargs`. That would demonstrate that even a simple func def, with a fixed # of parameters, can be supplied a dictionary. That is, it doesn't require anything fancy in the definition. THEN you might add a second example, WITH **kwargs in definition, and show how EXTRA items in dictionary are available via that. – ToolmakerSteve Dec 16 '13 at 21:03
  • 1
    I have seen this happen in various libraries' source code and was so confused. Thanks for clearing it up! – Craig Labenz Feb 03 '14 at 20:04
  • 3
    The fourth formal parameter above - **kwargs is necessary if you ever call func with a dictionary that contains keys other than 'a', 'b' and 'c'. – Eduardo Jan 15 '16 at 16:58
  • For me `print 'a:%s, b:%s, c:%s' % (a, b, c)` gives syntax error, however `print('a:%s, b:%s, c:%s' % (a, b, c))` works. Something with Python version ? Anyway thanks for this insight, until now I was using the more clunky `print('a:{}, b:{}, c:{}'.format(a, b, c))` – Axel Bregnsbo Jun 06 '20 at 06:36
  • This demonstrates that default arguments can be used without a pass-in as well as overwritten/specified. But I think the second example func(**kwargs) pass-in is really redundant when one can simply call with positional arguments >>> func('z', 'q', 'v'). Besides, if you ever do something like >>> func('p', **{'a' : 'z', 'b':'q', 'c':'v'}), you would get an error of multiple values for argument 'a'. – Leon Chang May 31 '21 at 18:07
24

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.

Christophe Roussy
  • 16,299
  • 4
  • 85
  • 85
  • 3
    The *required* variant is quite useful. It urges to give the args by name without providing defaults, which often makes no sense. – TNT Apr 20 '17 at 10:59
  • Default values look nice and can help you save time when you start out, but on the long run default values can be a PITA. – Christophe Roussy Dec 19 '17 at 12:09
11

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.

Gabriel Hurley
  • 39,690
  • 13
  • 62
  • 88
0

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 {}
jmunsch
  • 22,771
  • 11
  • 93
  • 114
0

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

sonictl
  • 63
  • 10