Writing functions

Author

Marie-Hélène Burle

Python comes with a number of built-in functions. Packages can provide additional ones. In many cases however, you will want to create your own functions to perform exactly the computations that you need.

In this section, we will see how to define new functions.

Syntax

The function definition syntax follows:

def <name>(<arguments>):
    <body>

Once defined, new functions can be used as any other function.

Let’s give this a try by creating some greeting functions.

Function without argument

Let’s start with the simple case in which our function does not accept any argument:

def hello():
    print('Hello')

Then we call it:

hello()
Hello

This was great, but …

hello('Marie')
TypeError: hello() takes 0 positional arguments but 1 was given

… it does not accept arguments.

Function with one argument

Let’s step this up with a function which can accept an argument:

def greetings(name):
    print('Hello ' + name)

This time, this works:

greetings('Marie')
Hello Marie

However, this does not work anymore:

greetings()
TypeError: greetings() missing 1 required positional argument: 'name'

:(

Function with a facultative argument

Let’s make this even more fancy: a function with a facultative argument. That is, a function which accepts an argument, but also has a default value for when we do not provide any argument:

def howdy(name='you'):
    print('Hello ' + name)

We can call it without argument (making use of the default value):

howdy()
Hello you

And we can call it with an argument:

howdy('Marie')
Hello Marie

This was better, but …

howdy('Marie', 'Paul')
TypeError: howdy() takes from 0 to 1 positional arguments but 2 were given

… this does not work.

Function with two arguments

We could create a function which takes two arguments:

def hey(name1, name2):
    print('Hello ' + name1 + ', ' + name2)

Which solves our problem:

hey('Marie', 'Paul')
Hello Marie, Paul

But it is terribly limiting:

# This doesn't work
hey()
TypeError: hey() missing 2 required positional arguments: 'name1' and 'name2'
# And neither does this
hey('Marie')
TypeError: hey() missing 1 required positional argument: 'name2'
# Nor to mention this...
hey('Marie', 'Paul', 'Alex')
TypeError: hey() takes 2 positional arguments but 3 were given

Function with any number of arguments

Let’s create a truly great function which handles all our cases:

def hi(name='you', *args):
    result = ''
    for i in args:
        result += (', ' + i)
    print('Hello ' + name + result)

And let’s test it:

hi()
hi('Marie')
hi('Marie', 'Paul')
hi('Marie', 'Paul', 'Alex')
Hello you
Hello Marie
Hello Marie, Paul
Hello Marie, Paul, Alex

Everything works!

Documenting functions

It is a good habit to document what your functions do. As with comments, those “documentation strings” or “docstrings” will help future you or other users of your code.

PEP 257—docstring conventions—suggests to use single-line docstrings surrounded by triple quotes.

Remember the function definition syntax we saw at the start of this chapter? To be more exhaustive, we should have written it this way:

def <name>(<arguments>):
    """<docstrings>"""
    <body>

Example:

def hi(name='you', *args):
    """Print a greeting"""
    result = ''
    for i in args:
        result += (', ' + i)
    print('Hello ' + name + result)

PEP 8—the style guide for Python code—suggests a maximum of 72 characters per line for docstrings.

If your docstring is longer, you should create a multi-line one. In that case, PEP 257 suggests to have a summary line at the top (right after the opening set of triple quotes), then leave a blank line, then have your long docstrings (which can occupy multiple lines), and finally have the closing set of triple quotes on a line of its own:

def <name>(<arguments>):
    """<summary docstrings line>"""

    <more detailed description>
    """
    <body>

Example:

def hi(name='you', *args):
    """Print a greeting

    Accepts any number of arguments
    """
    result = ''
    for i in args:
        result += (', ' + i)
    print('Hello ' + name + result)

You can (and should) document modules, classes, and methods in the same way.

You can now access the documentation of your function as you would any Python function:

help(hi)
Help on function hi in module __main__:

hi(name='you', *args)
    Print a greeting
    
    Accepts any number of arguments

Or:

print(hi.__doc__)
Print a greeting

    Accepts any number of arguments