Define and call functions in Python (def, return)
This article provides a comprehensive guide to defining and calling (executing) functions in Python.
Refer to the following articles for information on lambda expressions, docstrings, and command line arguments.
- Lambda expressions in Python
- Python docstring formats (styles) and examples
- Command line arguments in Python (sys.argv, argparse)
You can find the official documentation for defining functions here:
How to define and call a function in Python
In Python, functions are defined using def
statements, with parameters enclosed in parentheses ()
, and return values are indicated by the return
statement.
def function_name(parameter1, parameter2...):
do_something
return return_value
Note that blocks are expressed with indentation (usually four spaces) rather than brackets.
To call a defined function, use the following syntax:
function_name(argument1, argument2...)
Example:
def add(a, b):
x = a + b
return x
x = add(3, 4)
print(x)
# 7
Parameters and return values can be omitted if not necessary.
def hello():
print('Hello')
hello()
# Hello
Detailed explanations about arguments and return values are provided below.
Note that while the Python coding standard PEP8 recommends leaving two blank lines before and after top-level function definitions, only one blank line is used in the sample code for convenience.
Positional and keyword arguments
Parameters are defined by separating them with commas inside the parentheses of function_name()
. The following example demonstrates a simple function that outputs the arguments using f-strings.
def func(a, b, c):
print(f'a={a}, b={b}, c={c}')
Positional argument
When calling a function, specify the values in the defined order.
func(1, 10, 100)
# a=1, b=10, c=100
If the number of values specified when calling the function does not match the number of parameters in the function definition, a TypeError
will occur.
# func(1)
# TypeError: func() missing 2 required positional arguments: 'b' and 'c'
# func(1, 10, 100, 1000)
# TypeError: func() takes 3 positional arguments but 4 were given
Keyword argument
You can specify a value as parameter_name=value
when calling a function. In this case, the arguments can be specified in any order.
func(b=10, c=100, a=1)
# a=1, b=10, c=100
Not all arguments need to be specified by keywords. You can specify some arguments by position and others by keyword. However, after specifying an argument by keyword, all subsequent arguments must also be specified by keywords.
func(1, c=100, b=10)
# a=1, b=10, c=100
# func(a=1, 10, 100)
# SyntaxError: positional argument follows keyword argument
Positional/keyword-only parameter
Positional-only parameter (Python 3.8 or later)
When defining a function, if /
is used as a parameter, the parameters preceding /
are treated as positional-only.
Positional-only parameters cannot be passed by keyword. Parameters after /
can be passed by keyword.
def func_pos_only(a, b, /, c):
print(f'a={a}, b={b}, c={c}')
# func_pos_only(a=1, b=10, c=100)
# TypeError: func_pos_only() got some positional-only arguments passed as keyword arguments: 'a, b'
func_pos_only(1, 10, 100)
# a=1, b=10, c=100
func_pos_only(1, 10, c=100)
# a=1, b=10, c=100
If you define a function with /
at the end, such as func(a, b, c, /)
, all parameters are positional-only.
The positional-only parameter using /
was introduced in Python 3.8 and unavailable in earlier versions.
Keyword-only parameter
When defining a function, if *
is used as a parameter, the parameters following *
are treated as keyword-only.
Keyword-only parameters must be specified by keywords, while parameters before *
can be specified by either position or keyword.
def func_kw_only(a, b, *, c):
print(f'a={a}, b={b}, c={c}')
# func_kw_only(1, 10, 100)
# TypeError: func_kw_only() takes 2 positional arguments but 3 were given
func_kw_only(1, 10, c=100)
# a=1, b=10, c=100
func_kw_only(1, c=100, b=10)
# a=1, b=10, c=100
If you define a function with *
at the beginning, such as func(*, a, b, c)
, all parameters are keyword-only.
Positional-only parameter and keyword-only parameter
You can use /
and *
simultaneously in a function definition. Parameters before /
are position-only, those after *
are keyword-only, and those between /
and *
can be specified by either position or keyword.
def func_pos_kw_only(a, /, b, *, c):
print(f'a={a}, b={b}, c={c}')
# func_pos_kw_only(1, 10, 100)
# TypeError: func_pos_kw_only() takes 2 positional arguments but 3 were given
# func_pos_kw_only(a=1, b=10, c=100)
# TypeError: func_pos_kw_only() got some positional-only arguments passed as keyword arguments: 'a'
func_pos_kw_only(1, 10, c=100)
# a=1, b=10, c=100
func_pos_kw_only(1, c=100, b=10)
# a=1, b=10, c=100
You cannot use /
before *
.
# def func_pos_kw_only(a, *, b, /, c):
# print(f'a={a}, b={b}, c={c}')
# SyntaxError: invalid syntax
Default parameter values
You can set a default value for a parameter by defining parameter_name=default_value
in the function definition.
If a default value is set, you can omit the argument when calling the function. Of course, if you specify a different value, that value will be used.
def func_default(a, b, c=100):
print(f'a={a}, b={b}, c={c}')
func_default(1, 10)
# a=1, b=10, c=100
func_default(1, 10, 200)
# a=1, b=10, c=200
Placing a default parameter before an ordinary parameter without a default value in the function definition causes a SyntaxError
.
# def func_default(a=1, b, c=100):
# print(f'a={a}, b={b}, c={c}')
# SyntaxError: non-default argument follows default argument
Note that using mutable objects, such as lists or dictionaries, as default values can lead to unexpected behavior, as the same objects will always be used when calling the function. For more details, see the following article.
Variable-length arguments
When defining a function, you can add *
and **
to parameter names to allow variable-length arguments. This enables you to specify any number of arguments when calling the function.
By convention, *args
and **kwargs
are often used, but other names with *
and **
prefixes are also acceptable.
*args
: Receive multiple arguments as a tuple
If you prefix a parameter name with *
, multiple arguments will be received as a tuple.
def func_args(*args):
print(args)
func_args(1, 10)
# (1, 10)
func_args(1, 10, 100, 1000)
# (1, 10, 100, 1000)
**kwargs
: Receive multiple keyword arguments as a dictionary
If you prefix a parameter name with **
, multiple keyword arguments will be received as a dictionary (dict
).
def func_kwargs(**kwargs):
print(kwargs)
func_kwargs(a=1, b=10)
# {'a': 1, 'b': 10}
func_kwargs(c=1, b=10, d=1000, a=100)
# {'c': 1, 'b': 10, 'd': 1000, 'a': 100}
Be careful about the order when combining positional arguments with *args
and **kwargs
. See the following article for details.
Unpack lists, tuples, and dictionaries
Unpack lists or tuples
When calling a function, prefixing a list or tuple with *
unpacks its elements and specifies them as positional arguments. A TypeError
is raised if the number of elements in the list or tuple does not match the number of arguments in the function.
def func(a, b, c):
print(f'a={a}, b={b}, c={c}')
l = [1, 10, 100]
func(*l)
# a=1, b=10, c=100
l = [1, 10]
# func(*l)
# TypeError: func() missing 1 required positional argument: 'c'
Unpack dictionaries
If you prefix a dictionary with **
when calling a function, its keys and values are unpacked as names and values of the arguments and specified as keyword arguments. A TypeError
is raised if the number of keys in the dictionary does not match the number of argument names in the function, or if there are non-matching keys.
d = {'a': 1, 'b': 10, 'c': 100}
func(**d)
# a=1, b=10, c=100
d = {'a': 1, 'b': 10, 'x': 100}
# func(**d)
# TypeError: func() got an unexpected keyword argument 'x'
For more information, see the following article.
Return value
Basics of return
The return value of the function is specified by the return
statement.
def func_return(a, b):
return a + b
x = func_return(3, 4)
print(x)
# 7
print(type(x))
# <class 'int'>
The return value type depends on the types of the arguments and the processing within the function.
x = func_return(0.3, 0.4)
print(x)
# 0.7
print(type(x))
# <class 'float'>
Functions that return None
return
is not mandatory in a function and can be omitted if it is unnecessary to return a value.
A function without return
returns None
. In the following example, pass
is used to prevent an error when the def
block is empty.
def func_none():
# do something
pass
x = func_none()
print(x)
# None
If you omit the value after return
, None
is returned.
def func_none2():
return
x = func_none2()
print(x)
# None
Of course, you can explicitly write return None
.
def func_none3():
return None
x = func_none3()
print(x)
# None
Specify multiple return values
Specifying multiple values separated by commas with return
returns a tuple.
def func_return_multi(a, b):
return a + b, a * b, a / b
x = func_return_multi(3, 4)
print(x)
# (7, 12, 0.75)
print(type(x))
# <class 'tuple'>
You can unpack each value and assign it to a variable.
x, y, z = func_return_multi(3, 4)
print(x)
# 7
print(y)
# 12
print(z)
# 0.75