In this post, we will clarify some terminology associated with passing data into functions commonly known as Function Parameters in Python. This terminology relates to the parameters defined as part of the function header and the data passed into the function via these parameters:
- A parameter is a variable defined as part of the function header and is used to make data available within the function itself.
- An argument is the actual value or data passed into the function when it is called. The data will be held within the parameters.
Unfortunately, many developers use these terms interchangeably but it is worth being clear on the distinction.
Multiple Function Parameters in Python
So far the functions we have defined have only had zero or one parameters; however that was just a choice. We could easily have defined a function which defined two or more parameters. In these situations, the parameter list contains a list of parameter name separated by a comma.
def greeter(name, message): print ("Welcome to ", name, " - ", message) greeter ('DroxElement', 'Space for Programming')
Here the greeter function takes defines two parameters; name and message. These parameters (which are local to the function and cannot be seen outside of the function) are then used within the body of the function.
The output is
Welcome to DroxElement - Space for Programming
We can have any number of parameters defined in a function (prior to Python 3.7 there was a limit of 256 parameters; although if we have this many then probably we have a major problem with the design of the function; however this limit has now gone; that means we can have unlimited number of parameters in our function).
Also Read : Functions in Python
Default Parameter Values
Once we have one or more parameters we may want to provide default values for some or all of those parameters; particular for ones which might not be used in most cases.
This can be done very easily in Python; all that required is that the default value must be declared in the function header along with the parameter name.
If a value is supplied for the parameter, then it will override the default. If no value is supplied when the function is called, then the default will be used.
For example, we can modify the
greeter() function from the previous section to provide a default message such as ‘Restless Programmers’.
def greeter(name, message = 'Restless Programmers'): print ("Welcome to ", name, " - ", message) greeter ('DroxElement') greeter ('DroxElement', 'Space for Programming')
Now we can call the
greeter() function with one or two arguments. When we run this example, we get:
Welcome to DroxElement - Restless Programmers Welcome to DroxElement - Space for Programming
As we can see from this, in the first example (where only one argument was provided) the default message was used. However, in the second example where a message was provided, along with the name, then that message was used instead of the default.
Note we can use the terms mandatory and optional for the parameters in
greeter(). In this case,
- name is mandatory field/parameter
- message is an optional field/parameter (as it has a default value).
One point to note is that any number of parameters in a function’s parameter list can have a default value. However once one parameter has a default value all remaining parameters to the right must also have default values. For example, we could not define the greeter function as
def greeter(message = 'Restless Programmers', name): print ("Welcome to ", name, " - ", message)
As this would generate an error indicating that name must have a default value as it comes after (to the right) of a parameter with a default value.
So far we have relied on the position of a value to be used to determine which parameter that value is assigned to. In many cases, this is the simplest and cleanest option.
However, if a function has several parameters, some of which have default values, it may become impossible to rely on using the position of a value to ensure it is given to the correct parameter (because we may want to use some of the default values instead).
For example, let us assume we have a function with four parameters
def greeter (name, title = 'Er.', prompt = 'Welcome ', message = 'Live Long and Prosper'): print (prompt, title, name, ' - ', message)
This now raises the question how do we provide the
name and the
message arguments when we would like to have the default
The answer is to use named arguments (or keyword arguments). In this approach we provide the name of the parameter we want an argument/value to be assigned to; position is no longer relevant. For example,
greeter (message = 'We like Python', name = 'DroxElement')
In this example, we are using the default values for
prompt and have changed the order of
name. This is completely legal and results in the following output.
Welcome Er. DroxElement - We like Python
We can actually mix positional and named arguments in Python. For example, here ‘DroxElement’ is bound to the name parameter as it is the first parameter, but ‘We like Python’ is bound to message parameter as it is a named argument.
greeter ('DroxElement', message = 'We like Python')
However, we cannot place positional arguments after a named argument, so we cannot write:
greeter (name = 'Droxy', 'We like Python')
As this will result in Python generating an error.
In some cases, we do not know hoe many arguments will be supplied when a function is called. Python allows us to pass an arbitrary number of arguments into a function and then process those arguments inside the function.
To define a parameter list as being of arbitrary length, a parameter is marked with an asterisk (*). For example,
def greeter (*args): for name in args: print ('Welcome', name) greeter ('Drox', 'Element', 'DroxElement')
Welcome Drox Welcome Element Welcome DroxElement
Note that this is another use of the for loop; but this time it is a sequence of strings rather than a sequence of integers that is being used.
Positional and Keyword Arguments
Some functions in Python are defined such that the arguments to the methods can either be provided using a variable number of positional or keyword arguments. Such functions have two arguments *args and **kwargs (for positional arguments and keyword arguments).
They are useful if we do not know exactly how many of either position or keyword arguments are going to be provided. For example, the function
my_function takes both a variable number of positional and keyword arguments.
def my_function (*args, **kwargs): for arg in args: print ('arg: ', arg) for key in kwargs.keys(): print ('key: ', key, ' has value: ', kwargs[key])
This can be called with any number of arguments of either type:
my_function ('Drox', 'Element', program = 'Python', version = '3.9') print('-' * 50)
which produce the output:
arg : Drox arg : Element key : program has value: Python key : version has value: 3.9
Also note that the keywords used for the arguments are not fixed. We can also define methods that only use one of the *args and **kwargs depending on the requirements.