Function Syntax and the Python Grammar
June 1, 2022
Overview
Python's grammar specifies how a function may be defined and called. Parameters are used to declare the input variables when a function is defined, and arguments are used to pass values to these parameters when a function is called.
Defining a Function
The grammar of a function definition allows for the specification of required and optional parameters, positional-only and keyword-only parameters, and variable-length parameters. For example, below is a valid function definition:
def f(a, b, /, c, d=1, *e, f=2, g, **h): ...
Required Parameters
Required parameters are parameters defined in a function that must be provided when the function is called (there is no default value).
Required parameters must come before optional parameters for all non keyword-only parameters (ie: everything before the first of either *
or **
).
Usage:
- to enforce the order of arguments when the function is called
Examples:
def f(a, b, c):
...
Optional Parameters
Optional parameters are parameters defined in a function with an associated default value mapped to them. Optional parameters allow arguments to be omitted when the function is called, with the default value being used if the argument is omitted.
Optional parameters are evaluated once when the module is loaded, not with each call to the function. If the default value is a mutable object, modifications to the value will affect the corresponding object in the calling environment.
Usage:
- to define sensible defaults and ensure that a function will run without every argument being provided
Examples:
def f(a=1, b=2, c=3):
...
Positional-Only Parameters
Positional-only parameters (referenced in PEP 570) are parameters that indicate that the arguments passed into a function call must be done by position only (ie: not by keyword). The /
operator is used in the function definition, indicating that all parameters to the left are positional-only parameters.
The /
operator may be defined once, and, if exists, at least one positional-only parameter must be defined.
Usage:
- to prevent function calls being coupled with parameter names that have no semantic meaning or which may change over time
- to allow a function to accept both positional arguments and keyword arguments with the same name
Examples:
def f(a, b, /, c):
...
def f(name, /, **kwargs):
return 'name' in kwargs
Variable-Length Positional-Only Parameters (*args
)
In a function definition, a parameter preceded by a single asterisk (*
) indicates argument tuple packing (the parameter name is commonly called *args
). The function accepts a variable number of positional arguments which will be unpacked as a tuple.
The *
operator cannot have a default value.
Usage:
- to allow a variable number of positional arguments to be passed into the function
Examples:
def f(*args):
...
Keyword-Only Parameters
Keyword-only parameters (referenced in PEP 3102) are parameters that indicate the arguments passed into a function call must be done by keyword only (ie: not by position). The *
operator is used in the function definition, indicating that all parameters to the right are keyword-only parameters.
The *
operator may be defined once, and, if exists, at least one keyword-only parameter must be defined.
Usage:
- to be explicit in the function call
- to prevent function calls being coupled with the order of parameters
Examples:
def f(a, b, *, c):
...
Variable-Length Keyword-Only Parameters (**kwargs
)
In a function definition, a parameter preceded by a double asterisk (**
) indicates argument dictionary packing (the parameter name is commonly called **kwargs
). The function accepts a variable number of keyword arguments which will be unpacked as a dictionary.
The **
operator cannot have a default value and no parameters may follow it.
Usage:
- to allow a variable number of keyword arguments to be passed into the function
Examples:
def f(**kwargs):
...
Calling a Function
The grammar of a function call allows for the specification of positional and keyword arguments, and variable-length arguments.
Positional Arguments
Positional arguments (required arguments) are arguments passed in the function call by binding argument values to parameter positions.
Positional arguments must be specified in order, and the number of arguments must match the number of parameters.
Examples:
def f(a, b, c):
...
f(1, 2, 3)
Variable-Length Positional Arguments
In a function call, an argument preceded by a single asterisk (*
) indicates that the argument should be unpacked as a tuple and passed to the function as separate positional arguments. This operator may be applied to any iterable object.
Examples:
def f(a, b, c):
...
x = (1, 2, 3)
f(*x)
Keyword Arguments
Keyword arguments (named arguments) are arguments passed in the function call by binding argument values to parameter keywords.
Keyword arguments may be specified in any order, and each keyword argument must match a parameter name.
Examples:
def f(a, b, c):
...
f(a=1, b=2, c=3)
Variable-Length Keyword Arguments
In a function call, an argument preceded by a double asterisk (**
) indicates that the argument should be unpacked as a dictionary and passed to the function as separate keyword arguments. This operator may be applied to any mapping object.
Examples:
def f(a, b, c):
...
x = {'a': 1, 'b': 2, 'c': 3}
f(**x)
Summary
Defining a function:
- a parameter name may be defined only once
- required parameters must come before optional parameters for all non keyword-only parameters (ie: everything before the first of either
*
or**
) - the
/
operator indicates that all parameters to the left (with at least one) are positional-only parameters - the
*
operator preceeding a single parameter indicates variable-length positional-only parameter packing- the parameter cannot have a default value
- the
*
operator indicates that all parameters to the right (with at least one) are keyword-only parameters - the
**
operator preceeding a single parameter indicates variable-length keyword-only parameter packing- the parameter cannot have a default value
- the
/
,*
and**
operators may each be defined once and must occur in the aforementioned order - no parameters may follow the
**
operator
Calling a function:
- positional arguments must come before keyword arguments
- the order of positional arguments matter
- the order of keyword arguments does not matter
- no argument may receive a value more than once
- all keyword arguments passed must match one of the parameter names accepted by the function
- the names of positional-only parameters can be used in
**kwargs
without ambiguity