Python Functions Tutorial

In this tutorial we learn how to group one or more statements into a function to facilitate code reuse throughout an application.

We cover how to define and call a function, with and without parameters, as well as how to return a value. Finally, we take a look at creating recursive functions.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

What is a function

A function is one or more statements, grouped together for reuse throughout our code.

So far, any functionality we wanted in our application was created directly. When an application becomes bigger and more complex, we need to separate our code into smaller sections of logic. We want one section of code to only be responsible for one task, so we separate the sections into functions, classes etc.

As an example, let’s create some simple functionality:

Example:
# number to check
num = 27

# if the number can be divided by two
# without a remainder, it's an even num
if num % 2 == 0:
    print(num, "is an even number")
else:
    print(num, "is an odd number")

The example above checks whether a number is even or odd. We can separate this logic into a function to allow for easy reuse.

How to define a function

The most basic function consists of the keyword def , an identifier, parameters, and at least one statement in its body.

Syntax:
def function_name():
	# statements

A function needs open and close parentheses after the name even if it doesn’t have any parameters.

Example: how to define a function
def print_message():
	print("Hello World")

In the example above all we do is print out a statement, but if we run the example nothing will happen. That’s because the function has been defined, but not yet used.

How to call (use) a function

Our simple function has now been defined but it won’t print anything until it is used. To use it, we have to call a function. We write its name, and any parameters needed inside the parentheses.

Syntax:
 function_name()

Once again, the parentheses are used even if the function doesn’t contain any parameters.

Example: how to call (use) a function
# definition
def print_text():
	print("Hello World")

# call
print_text()

If we run the example above we see that the code inside the function is executed and the message is printed.

How to define a function with parameters

We can give our function parameters to work with locally. The local scope means that those parameters will only be available to be used in the function, and not anywhere else inside our program.

Syntax:
def function_name(param_1, param_2, ...):
	# use param_1 and/or param_2 here

Our parameters are separated with commas.

Example: how to define a function with parameters
# definition
def print_text(message):
	print(message)

# call
print_text("Hello World")
print_text("Hello there")

In the example above we specify “message” as a parameter between the parentheses. We then use that local variable in the print function.

It would be similar to writing the following:

Example:
message = "Hello World"

print(message)

The only difference is that it’s inside a function, we can add more logic or parameters etc.

The function is silly because print already exists, but it’s an easy way to understand how it works. So now that we know how it works, let’s create a function for the odd/even number logic.

Example: odd or even function
def is_odd_or_even(num):
	if num % 2 == 0:
		print(num, "is an even number")
	else:
		print(num, "is an odd number")

In the example above our “num” parameter is our local variable that we use to do the calculations. We can now call this function with any number as a parameter.

Example: call the odd or even function
# definition
def is_odd_or_even(num):
	if num % 2 == 0:
		print(num, "is an even number")
	else:
		print(num, "is an odd number")

# calls
is_odd_or_even(5)
is_odd_or_even(10)
is_odd_or_even(27)
is_odd_or_even(-358)
is_odd_or_even(125987)
is_odd_or_even(-258749)
is_odd_or_even(-10)
is_odd_or_even(3.14)

In the example above, each time we call the function with a different number, we reuse the code inside the function. If we didn’t have the function we would need to write out the logic of the calculation each time.

Example:
num = 5
if num % 2 == 0:
	print(num, "is an even number")
else:
	print(num, "is an odd number")

num = -10
if num % 2 == 0:
	print(num, "is an even number")
else:
	print(num, "is an odd number")

num = 3.14
if num % 2 == 0:
	print(num, "is an even number")
else:
	print(num, "is an odd number")

# etc.

The function allows us to group code and reuse it in other places within our code without having to rewrite the logic.

The default function parameter value

We can specify a default value for a parameter in a function. Think of it as a fallback if no parameter is given.

To create a default value for a parameter we assign it the value we want.

Syntax:
def function_name(param = default_value):
	# statements
Example: a function with a default parameter
def alert(pop_up = True, email = False, mobile = False):
	if pop_up:
		print("Pop up alert!")
	if email:
		print("Email alert")
	if mobile:
		print("Mobile alert")

alert()

When we run the example above, we’ll see that even though we didn’t specify any parameters, the “pop_up” alert still triggered.

The defaults essentially turn the function call into the following.

Example:
def alert(pop_up, email, mobile):
	if pop_up:
		print("Pop up alert!")
	if email:
		print("Email alert")
	if mobile:
		print("Mobile alert")

alert(True, False, False)

Any parameters with defaults must be specified last in order. We cannot have a parameter with a default value, before any other parameters that don’t have defaults.

Example:
def alert(pop_up = True, email, mobile):
	pass

If we run the example above, we will see a SyntaxError explaining that a non-default argument follows a default argument.

The default parameter must be last in the list.

Example:
def alert(email, mobile, pop_up = True):
	pass

The example above will give no errors because we moved the parameter with the default value after the ones without a default value.

How to return a value from a function

Often, we want to return a value from the function to be used later on. To do this we use the return keyword.

Syntax:
def function_name():
	return # something
Example: return a value from a function
def add(num1 = 0, num2 = 0):
	return num1 + num2

In the example above we return the sum of “num1” and “num2”. We don’t just calculate the answer, we also give the answer back.

When we call the function it will calculate the sum and return the answer, so the answer will be a value we can use. We can either use it directly or store it for later use.

Example:
def add(num1 = 0, num2 = 0):
	return num1 + num2

# store the answer in a
# data container such as
# a variable
result = add(1, 1)
print(result)

# use the answer directly
print(add(5, 5))

In the example above, we use the variable “result” to store the answer by assigning the function call directly to the variable. We then print it for demonstration purposes.

We can call one function as a parameter inside another function, as seen in the second print statement above.

Recursion

In Python we are allowed to call a function inside of itself. Recursion is a common mathematical and programming concept, and when written correctly can be a very efficient and elegant approach.

Developers should be careful when using recursion because it’s easy to write an infinite function, much like an infinite loop, that will use increasing amounts of processing power (CPU) or memory (RAM).

To use recursion we call the function where needed within its own code block.

Example: recursion
def factorial(n):
	if n == 1:
		return 1
	else:
		return n * factorial(n-1)

print("The factorial of", 6, "is:", factorial(6))

In the example above, we call our function inside itself in the else statement. We do this because we need the result of the function - 1 until it reaches 1, in which case the factorial calculation ends and we get the final result.

For those who are interested in the factorial math, we’ll take a quick look at how it works. This may also help with understanding the recursion function.

A factorial multiplies all whole numbers from our chosen number (“n”) down to 1. In the example above our “n” is 6, so let’s use that:

Example: factorial
 n = 6 x 5 x 4 x 3 x 2 x 1 = 720

If you want to read more about factorials, check out the Wikipedia pageOpens up in a new page

Recursion loop

If a function goes into a loop because of recursion, the interpreter might show us a RecursionError.

Example:
def multiply_add(num1 = 0, num2 = 0):
	return multiply_add(1, 1) * 2

print(multiply_add(1, 1))

In the somewhat silly example above, the function can continue on almost infinitely. There is nothing that stops it in the logic, in which case the interpreter will tell us that we’ve reached the maximum recursion depth.

Output:
Traceback (most recent call last):
  File "C:/Users/Username/PycharmProjects/PyProjects/HelloWorld.py", line 4, in <module>
    print(multiply_add(1, 1))
  File "C:/Users/Username/PycharmProjects/PyProjects/HelloWorld.py", line 2, in multiply_add
    return multiply_add(1, 1) * 2
  File "C:/Users/Username/PycharmProjects/PyProjects/HelloWorld.py", line 2, in multiply_add
    return multiply_add(1, 1) * 2
  File "C:/Users/Username/PycharmProjects/PyProjects/HelloWorld.py", line 2, in multiply_add
    return multiply_add(1, 1) * 2
  [Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

Process finished with exit code 1

Recursion isn’t used often, except in cases where it makes sense to, like the factorial.

Summary: Points to remember

  • A function groups together sections of code and allows us to reuse that code without having to rewrite it.
  • We use a function by calling it with any required parameters.
  • A function can return a value with the return statement.
  • A function that calls itself may cause an infinite loop and crash the application.