Normal Arguments Vs. Keyword Arguments

Normal arguments vs. keyword arguments

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'}

What's the difference between arguments with default values and keyword-arguments?

Keyword arguments are how you call a function.

f( a=1, b=2, c=3, d=4 )

Default values are how a function is defined.

Any reason NOT to always use keyword arguments?

There isn't any reason not to use keyword arguments apart from the clarity and readability of the code. The choice of whether to use keywords should be based on whether the keyword adds additional useful information when reading the code or not.

I follow the following general rule:

  1. If it is hard to infer the function (name) of the argument from the function name – pass it by keyword (e.g. I wouldn't want to have text.splitlines(True) in my code).
  2. If it is hard to infer the order of the arguments, for example if you have too many arguments, or when you have independent optional arguments – pass it by keyword (e.g. funkyplot(x, y, None, None, None, None, None, None, 'red') doesn't look particularly nice).
  3. Never pass the first few arguments by keyword if the purpose of the argument is obvious. You see, sin(2*pi) is better than sin(value=2*pi), the same is true for plot(x, y, z).

In most cases, stable mandatory arguments would be positional, and optional arguments would be keyword.

There's also a possible difference in performance, because in every implementation the keyword arguments would be slightly slower, but considering this would be generally a premature optimisation and the results from it wouldn't be significant, I don't think it's crucial for the decision.

UPDATE: Non-stylistical concerns

Keyword arguments can do everything that positional arguments can, and if you're defining a new API there are no technical disadvantages apart from possible performance issues. However, you might have little issues if you're combining your code with existing elements.

Consider the following:

  • If you make your function take keyword arguments, that becomes part of your interface.
    You can't replace your function with another that has a similar signature but a different keyword for the same argument.
  • You might want to use a decorator or another utility on your function that assumes that your function takes a positional argument. Unbound methods are an example of such utility because they always pass the first argument as positional after reading it as positional, so cls.method(self=cls_instance) doesn't work even if there is an argument self in the definition.

None of these would be a real issue if you design your API well and document the use of keyword arguments, especially if you're not designing something that should be interchangeable with something that already exists.

Distinction between Default Argument Values and Keyword Arguments?

Both concepts are (mostly) distinct.

On function definition side, you have named parameters which have names, and you have variadic extensions, one for positional arguments (giving a tuple) and one for keyboard arguments (giving a dict).

Example:

def f(a, b=5, *c, **d): return a, b, c, d

This function has two named parameters (aand b) which can be used positional or via keyword. c and d take all others given.

You can call this function with positional arguments as well as with keyword arguments.

f(1)
f(a=1)

both return

1, 5, (), {}

because positional and keyword arguments are assigned to the named parameters.

You can as well do

f(a=5, foo=12) or f(5, foo=12) # -> 5, 5, (), {'foo': 12}
f(1, 2, 3) # -> 1, 2, (3,), {}

In the last example, the positional arguments 1 and 2 are given to the named parameters a and b; the exceeding 3 is put into the tuple c.

You cannot do

f(b=90) # no value for a
f(12, a=90) # two values for a

If there are still unclearities, please let me know.

Positional argument v.s. keyword argument

That text you quote seems to be confused about two totally different things:

  • Positional and keyword arguments are a feature of calls to a function (see Python reference section 5.3.4 Calls).
  • Default values are a feature of function definitions, as per section 7.6 Function definitions

I suspect the people who put together that course-ware weren't totally familiar with Python :-) Hence that link you provide is not a very good quality one.


In your call to your function, you're using the "keyword argument" feature (where the argument is named rather than relying on its position). Without that, values are bound to names based on order alone. So, in this example, the two calls below are equivalent:

def process_a_and_b(a, b):
blah_blah_blah()

process_a_and_b(1, 2)
process_a_and_b(b=2, a=1)

By further way of example, refer to the following definition and calls:

def fn(a, b, c=1):        # a/b required, c optional.
return a * b + c

print(fn(1, 2)) # returns 3, positional and default.
print(fn(1, 2, 3)) # returns 5, positional.
print(fn(c=5, b=2, a=2)) # returns 9, named.
print(fn(b=2, a=2)) # returns 5, named and default.
print(fn(5, c=2, b=1)) # returns 7, positional and named.
print(fn(8, b=0)) # returns 1, positional, named and default.


Related Topics



Leave a reply



Submit