Python informer

Declaring functions

You should hopefully already be familiar with how Python uses simple functions. This tutorial looks at more advanced ways to declare function parameters.

A simple function

Here is a simple Python function declaration, that we will extend in this article:

def fancy_print(s):
out = '[' + s + ']'
print(out)


This is simple enough, the function takes one parameter, and whatever value you pass in gets printed out with enclosing square brackets.

Here is how we would call it:

fancy_print('Hello')


The result would be:

[Hello]


Optional parameters

Suppose we wanted to extend our function so that instead of enclosing our output string in square brackets, we could choose what symbols to use. That is fairly easy to do:

def fancy_print(s, before, after):
out = before + s + after
print(out)

fancy_print('Hello', '<', '>')   # Prints '<Hello>'


This is good, but what if we usually want to use square brackets, and only use different brackets quite rarely. In that case we can use optional parameters (sometimes called defaulted parameters), like this:

def fancy_print(s, before='[', after=']'):
out = before + s + after
print(out)


The function now has one mandatory parameter, s, and two optional parameters, before and after. We only need to supply the optional parameters if we don’t want to use the default values. Here are some examples:

fancy_print('Hello')             # Prints '[Hello]'
fancy_print('Hello', '(')        # Prints '(Hello]'
fancy_print('Hello', '<', '>')   # Prints '<Hello>'


In this case:

• If we supply one parameter, s, the default square brackets are used.
• If we supply two parameters, s and before, the opening square bracket is replaced by the extra parameter.
• If we supply three parameters, s, before and after, both square brackets are replaced by the extra parameters.

Recipe for optional parameters

In a function declaration, the optional parameters must be placed after the non-optional parameters.

This is simply to avoid confusion. For example, suppose you were allowed to declare a function like this:

def fancy_print(before='[', after=']', s):  # You CAN'T do this!


This declaration is actually a syntax error, which makes sense if you think about it. The behaviour if you call this function with 1 or 2 parameters would be quite unclear - should the optional parameters take the values (leaving s undefined) or should s be assigned (breaking the order of the parameters)?

Variable number of parameters

Some Python functions, for example the print functions can accept any number of parameters. You can pass in as many values as you like and it will print them all:

print(1, 'xyz', 9)    # prints 1 xyz 9


How would you go about creating a function like this? Here is how we could make a multiple parameter version of fancy_print:

def multi_print(*args):
for s in args:
out = '[' + s + ']'
print(out)

multi_print('abc', 'defgh', 'XYZ')


Notice that the *args parameter has an asterisk in front of it. This identifies it as a variable length argument list. Although it is often given the name *args, you can give it any valid name, of course. You could call it *myparams, for example

What this parameter does is collect all the parameters passed in, and place them in a tuple. Inside the body of the function, you can access the tuple of values via the args variable.

Our code loops over the tuple, and prints:

[abc]
[defgh]
[XYZ]


It is valid to call multi_print with no parameters. The tuple will be empty, and nothing will be printed.

Mixing parameter types

You can mix fixed and variable parameters in a function. For example we could add a title to our multi_print function:

def multi_print(title, *args):
print(title)
print('--------')
for s in args:
out = '[' + s + ']'
print(out)

multi_print('My list', 'abc', 'defgh', 'XYZ')


Here, title picks up the first parameter value, and args gets any remaining parameters as a tuple. The function must be called with at least one parameter, because title needs a value. Here is what it prints:

My list
--------
[abc]
[defgh]
[XYZ]


You can also add defaulted parameters. Here we will add back the before and after parameters from the original code above:

def multi_print(title, *args, before='[', after=']'):
print(title)
print('--------')
for s in args:
out = before + s + after
print(out)

multi_print('My list', 'abc', 'defgh', 'XYZ', before='<', after='>')


This prints:

My list
--------
<abc>
<defgh>
<XYZ>


Keyword arguments

Keyword arguments are a bit like variable argument lists, but they work with named parameters. The are declared like this:

def some_function(**kwargs):


The form **kwargs identifies it as a keyword argument list (it doesn’t have to be called kwargs of course). It is called like this:

some_function(name='count', value=1):


This allows you to pass in named parameters that some_function doesn’t even know about until it is called. The parameters are stored in a dictionary, accessed by the variable kwargs. Here is a simple function that uses this:

def kw_test(**kwargs):
for kw in kwargs:
print(kw, 'is', kwargs[kw])

kw_test(name='count', value=1)


This prints:

name is count
value is 1


An example of keyword arguments in action is the Python dictionary constructor:

d = dict(type='hat', style='stetson', color='brown', size='10')


This creates a dictionary like this:

{'style': 'stetson', 'color': 'brown', 'size': '10', 'type': 'hat'}


One thing to note about this is that the dictionary keys must be strings that form valid Python variable names. In general, of course, a dictionary key can be any immutable object.

Recipe for mixing parameters

There are four different ways of declaring parameters in Python functions:

• Non-defaulted parameters - normal parameters, eg s
• Variable length argument list, eg *args (there cannot be more than one of these)
• Defaulted parameters, eg before='['
• Keyword argument list, eg **kwargs (there cannot be more than one of these)

It would be quite rare to use all of these, but is isn’t impossible. In general it is best to declare the arguments in the order shown, that is:

• All the non-defaulted parameters, it there are any
• The variable length argument list, is there is one
• All the defaulted parameters, it there are any
• The keyword argument list, is there is one

Most other combinations will cause syntax errors. Some other combinations are legal but generally not that useful.

Summary

Python provides several ways to add optional parameters to functions. This allows you to add extra functionality without complicating the default use of the function.