Argument Types in Python Functions: Positional and Keyword Arguments

This post is about using positional arguments and keyword arguments.

Table of Contents

Parameters and Arguments

Some definitions to start.

def func(param1, param2):
    pass
    
func("value1", "value2")
func(param1="value1", param2="value2")
(param1, param2) - function signature
param1, param2 - parameters

Parameters are the names in the function signature. These names can be used as local variable names within a function.

"value1", "value2" - positional arguments
param1="value1", param2="value2" - keyword arguments

Arguments are values passed to a function when it is called. We can use a function multiple times with different values.

func("value1", "value2") - function call with positional arguments
func(param1="value1", param2="value2") - function call with keyword arguments

Positional and keyword arguments are types of arguments.


Parameters can also be of different types. With different parameter types, we can control what types of arguments a function can accept and how those arguments can be combined.

If we examine this function, we see that the parameter type allows both types of arguments.

from inspect import signature

# There are no special characters in the function signature (/, *, **),
just a list of parameters.
def func(param1, param2):
    pass
    
for param in signature(func).parameters.values():
    print(param.name, param.kind)
    
# param1 POSITIONAL_OR_KEYWORD
# param2 POSITIONAL_OR_KEYWORD

This is the default parameter kind.


Simultaneous use of both types of arguments.

def func(param1, param2):
    pass

# positional argument for the first parameter
# keyword argument for the second parameter
func("value1", param2="value2")

There is one restriction on the simultaneous use of different types of arguments. Positional arguments precede keyword arguments.

func(param1="value1", "value2")
# SyntaxError: positional argument follows keyword argument

In the following examples, the function accepts both positional and keyword arguments.


Positional Arguments

Positional arguments are a sequence of values in a function call.

You need to pay attention to the order in which positional arguments are passed to the function.

def func(first_name, last_name):
    print(f"Name: {first_name} {last_name}")
    
func("Nataliia", "Bondarenko")
# Name: Nataliia Bondarenko

func("Bondarenko", "Nataliia")
# Name: Bondarenko Nataliia
func("Nataliia", "Bondarenko")

"Nataliia" is in the same position as first_name, and "Bondarenko" is in the same position as last_name.

func("Bondarenko", "Nataliia")

"Bondarenko" is in the same position as first_name, and "Nataliia" is in the same position as last_name.

"Nataliia Bondarenko" or "Bondarenko Nataliia" are allowed to be used. Confusion with argument positions is not critical here. But it is logically incorrect: first_name="Bondarenko" and last_name="Nataliia".

Positional arguments are convenient because we can write less code. We don't need to add the parameter name to each value. On the other hand, we need to remember the correct order of passing arguments.


Keyword Arguments

Keyword arguments are param=value pairs in a function call.

Argument position is unimportant as long as all arguments are keyword arguments.

def func(first_name, last_name):
    print(f"Name: {first_name} {last_name}")
    
func(first_name="Nataliia", last_name="Bondarenko")
# Name: Nataliia Bondarenko

func(last_name="Bondarenko", first_name="Nataliia")
# Name: Nataliia Bondarenko

Keyword arguments are convenient because we understand which value corresponds to which parameter. On the other hand, if we want to rename function parameters, the code that uses the old parameter names must be rewritten.


Default Values

Parameters can have default values. Such values are specified in the function signature.

For the next example, we will rewrite our function. In this case, the word order is important, otherwise the full name will be printed incorrectly. order="surname first" is default argument.

Default arguments are specified in the function signature after parameters that have no default values.

def func(last_name, first_name, patronymic, order="surname first"):
    """The function outputs the full name in two correct forms."""
    
    if order == "forename first":
        print(f"Name: {first_name} {patronymic} {last_name}")
    else: # surname first
        print(f"Name: {last_name} {first_name} {patronymic}")

We can omit parameters that have default values or set them to new values.

func("Bondarenko", "Nataliia", "Volodymyrivna")
# Name: Bondarenko Nataliia Volodymyrivna
func("Bondarenko", "Nataliia", "Volodymyrivna", "forename first")
# Name: Nataliia Volodymyrivna Bondarenko

We can also use keyword arguments.

func(last_name="Bondarenko", first_name="Nataliia",
     patronymic="Volodymyrivna", order="forename first")
# Name: Nataliia Volodymyrivna Bondarenko

Default values are useful when we have a long list of parameters that are auxiliary to their purpose.

If there were no default values, we would have to provide values for all of these parameters.

>>> help(open)
Help on built-in function open in module io:

open(file, mode='r', buffering=-1, encoding=None,
     errors=None, newline=None, closefd=True, opener=None)

The next example shows how we can use both positional and keyword arguments in the built-in function open. The positional argument here is the path to the file to open. All other values are predefined. So, if we want to override a certain default value, we can use the keyword argument.

with open("filename.txt", newline="", encoding="utf-8") as f:
    data = f.read(200)
print(data)
# some text

Popular posts from this blog

Tkinter Button Widget