ᚱᛗ
© 2022
Powered by Hugo

Default, Positional and Keyword Arguments

Table of Contents

Summary

The difference between parameters and arguments, and the different ways and conventions in which arguments can be passed to a function in Python.

Paremeters vs Arguments

Parameters are the names of the inputs defined in the function signature, whereas arguments are the actual values passed when calling it.

def func(foo, bar=None, **kwargs):
    pass
# foo, bar and kwargs are params

func(42, bar=300, extra=variable)
# 42, 300 and variable are arguments

Default Arguments

The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow.

def effusive_hello(effusiveness=3):
    return "Hello and welcome" + "!" * effusiveness


print(effusive_hello())  # Hello and welcome!!!
print(effusive_hello(7))  # Hello and welcome!!!!!!!

Standard Way (Positional and/or Keyword)

By default, arguments may be passed by position or by keyword, no restriction is imposed.

def standard_args(arg1, arg2):
    return arg1 + ", " + arg2

# all these work:
standard_args("this", "that")  # 'this, that'
standard_args(arg1="this", arg2="that")  # 'this, that'
standard_args("this", arg2="that")  # 'this, that'
standard_args(arg2="that", arg1="this")  # 'this, that'
# does not work (positional arguments must come first):
standard_args(arg2="that", "this")
SyntaxError: positional argument follows keyword argument

Positional Arguments Only

Any arguments preceding the / operator are deemed positional. Their order must be respected when calling the function—keywords cannot be used.

def positional_function(arg1, arg2, /):
    return arg1 + ", " + arg2

positional_function(arg1="this", arg2="that")  # TypeError
positional_function("this", "that")  # 'this, that'

The first call function returns TypeError: positional_function() got some positional-only arguments passed as keyword arguments: 'arg1, arg2'. The second call works as expected.

Keyword Arguments Only

Any arguments succeeding the * operator must be provided with their associated keywords—order does not matter.

def kwd_function(*, arg1, arg2):
    return arg1 + " plus " + arg2

kwd_function("this", "that")  # TypeError
kwd_function(arg1="this", arg2="that")  # "this plus that"
kwd_function(arg2="that", arg1="this")  # "this plus that"

The first function call returns TypeError: kwd_function() takes 0 positional arguments but 2 were given. The second call works as expected. The third call inverts the order in which the arguments are given, but since they are named, the result is not altered.

Mixing Conventions

All three conventions can be combined as long as their individual rules are respected. That is to say, positional arguments come first (followed by /), standard arguments (either positional or keyword) come second, keyword arguments come third (preceded by *).

# more generally
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
    pass

Use-Case Guidance

  1. Positional-only:
    • If you want the name of the parameters to not be available to the user
    • If parameter names have no real meaning
    • If you want to enforce the order of the arguments when the function is called
    • For APIs development, to prevent breaking API changes if the parameter’s name is modified in the future
  2. Keyword-only:
    • If names have meaning and the function definition is more understandable by being explicit with names
    • If you want to prevent users relying on the position of the argument being passed