Parameter Types in Python Functions
For more information about argument types, see Argument Types in Python Functions.
Parameter Types and Argument Usage
positional-or-keyword parameters
This is a common parameter type in Python functions. If there are no special characters (/, *, **) in the function signature, we can use both positional and keyword arguments.
def func(param1, param2): # function signature with parameters pass # function call with positional arguments func("value", "other value") # function call with keyword arguments func(param1="value", param2="other value") # or both func("value", param2="other value")
positional-only parameters
The function accepts only positional arguments. All arguments that match the parameters specified before the slash must be positional arguments.
def func(param, /): pass # function call with positional argument func("value")
Often, positional-only parameters are used when the parameter names don't matter.
def func(x, y, /): return x + y func(2, 3)
PEP 570 explains in detail why this type of parameter was added to Python functions.
keyword-only parameters
The function accepts arguments in the form of param=value
pairs. All arguments that match parameters specified after an asterisk (*) must be keyword arguments.
def func(*, param): pass # function call with keyword argument func(param="value")
If the order in which the arguments are passed or their position matters to the logic of the function, then it is better to use the keyword arguments.
def devide(*, dividend, divisor): return dividend / divisor # Regardless of the order in which the arguments are passed, # we will get the correct result: 2 divided by 3, not 3 divided by 2. devide(dividend=2, divisor=3) devide(divisor=3, dividend=2)
var-positional parameters
The function can accept an arbitrary sequence of positional arguments. Inside the function, args is used as a tuple.
def func(*args): print(args) # function call with positional argument func("value") # ('value',) # var-positional parameters can be optional func() # ()
var-keyword parameters
The function can take arbitrary keyword arguments. Inside the function, kwargs is used as a dict.
def func(**kwargs): print(kwargs) # function call with keyword argument func(param="value") # {'param': 'value'} # var-keyword parameters can be optional func() # {}
*Args and **Kwargs Examples
*args and **kwargs are often used in pairs. In this case, we can use both positional and keyword arguments.
def func(*args, **kwargs): print(args, kwargs) func("value") # ('value',) {} func(param="other value") # () {'param': 'other value'} func("value", param="other value") # ('value',) {'param': 'other value'} func() # () {}
These parameter types are useful for writing wrappers and decorators. In the following example, we need to pass arbitrary arguments.
from functools import wraps def exceptions_decorator(func): @wraps(func) def wrapper(*args, **kwargs): try: # my_func code runs here return func(*args, **kwargs) except Exception as e: print(f"{e.__class__.__name__}: {e} " \ f"in {func.__name__}") # do something return wrapper @exceptions_decorator def my_func(a, b): return a / b my_func(2, 0) # ZeroDivisionError: division by zero in my_func
*args and **kwargs can be used in class methods, particularly in the __init__
method. But the next example will show this pair in another method of the class.
import argparse from inspect import signature print(signature(argparse.ArgumentParser.add_argument)) # (self, *args, **kwargs)
The argparse module is designed to create a CLI in Python. The add_argument
method of the ArgumentParser class is for adding command-line program features.
The first values accepted in the method are names or flags. These are arbitrary values that we can choose ourselves (*args). All other values are passed as keyword arguments and correspond to **kwargs.
import argparse parser = argparse.ArgumentParser() parser.add_argument("foo", help="This is name foo", type=int) parser.add_argument("-b", "--bar", help="This is flag -b/--bar", action="store_true")
The parser takes values from args and kwargs to generate the CLI options.
add_argument("foo", help="This is name foo", type=int)
"foo"
is a positional argument passed to the add_argument
method.help="..."
and type=int
are keyword arguments passed to the add_argument
method.add_argument("-b", "--bar", help="This is flag -b/--bar", action="store_true")
"-b"
and "--bar"
are positional arguments passed to the add_argument
method.help="..."
and action="store_true"
are keyword arguments passed to the add_argument
method.Although the add_argument
method has some restrictions on what you can pass in it, it is also flexible in accepting arguments.
Combinations of Parameters
A general rule for using arguments is that positional arguments precede keyword arguments.
Accordingly, positional-only and var-positional parameters precede keyword-only and var-keyword parameters. Positional-or-keyword parameters are also specified at the beginning of the function signature.
The following conditions must be taken into account:
The longest possible combinations of different types of parameters:
1.(positional-only, /, positional-or-keyword, *, keyword-only, **kwargs)
2.(positional-only, /, positional-or-keyword, *args, **kwargs)
3.(positional-only, /, *args, positional-or-keyword, **kwargs)
In the second example, the positional-or-keyword parameter cannot take a value in the form of a keyword argument because it is followed by *args. Otherwise, we will get a SyntaxError.
In the third example, the positional-or-keyword parameter is forced to be a keyword-only because *args precedes it. Otherwise, we will get a TypeError.
Below are examples of the practical use of different types of parameters.
positional-or-keyword and keyword-only parameters
In some cases, especially if there are many parameters, it is convenient to combine positional and keyword arguments in a function call.
Parameters in such functions often have default values. When calling the function, it is not necessary to pass values to such parameters.
>>> import glob >>> help(glob.glob) Help on function glob in module glob: glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False) ... >>> glob.glob("*.txt") ['LICENSE.txt', 'NEWS.txt']
positional-only and keyword-only parameters
This example is similar to the previous one. There is also a main positional argument here. Values for key
and reverse
are optional.
>>> help(sorted) Help on built-in function sorted in module builtins: sorted(iterable, /, *, key=None, reverse=False) ... >>> sorted([2, 1, 3]) [1, 2, 3] >>> sorted(["giraffe", "lion", "python"], key=len) ['lion', 'python', 'giraffe']
var-positonal parameters
If *args precedes the rest of the parameters, they become keyword-only parameters. To distinguish args from the values of other parameters, we are forced to use keyword arguments for those parameters.
The following function converts all non-keyword arguments to strings and prints them.
>>> help(print) Help on built-in function print in module builtins: print(*args, sep=' ', end='\n', file=None, flush=False) ... >>> print("print is a", print, "in module", print.__module__) print is a <built-in function print> in module builtins >>> print(1, 2, 3, sep="-") 1-2-3