Functions are the building blocks of computer programs. When used correctly, functions allow you to reuse a lot of the code you write making your programs shorter and more readable.

Python, like all programming languages, has a specific set of rules that define how functions should be used. This article will explain the specifics of using Python functions, from definition to invocation.

What is a Function?

Programmers frequently aim to write reusable code. To avoid having to copy and paste the same code snippet each time we’d like to use it, functions allow us to package code and execute it anywhere in the program by simply calling the relevant function. In this manner, a series of instructions that might span over a hundred lines can be executed in one function call via a single line of code.

Reduced redundancy in the code also simplifies debugging. Rather than having to manually find and update buggy code at every place in a program, a function requires only one change — at the place where it’s defined. Once a function has been redefined, calling it will always execute the code’s updated version. 

As our programs become lengthier, putting all the pieces together can get complicated. Focusing on the practical details of implementation can get in the way of efficient problem-solving. Functions serve as a layer of abstraction over the nitty-gritty by their conceptual simplification of problems.

Now that we’ve defined functions and why they’re beneficial, let’s now conduct a sample implementation of a function definition in Python.

Elements of a Python Function Definition

Let’s analyze the following function definition template, element-by-element.

def Keyword

The def keyword stands for “define.” It’s used to preface Python function definitions.

Name

After the def keyword, you’ll see a function name. A name should describe the function’s given task and adhere to the Python style guidelines. Additionally, a function name should be written in lowercase characters with multiple words separated with an underscore.

Parameters

Immediately after the function’s name, you’ll see the function’s parameters defined within a set of parentheses. Parameters define the values that we’ll pass on to the function. 

Colon

A colon written after the parentheses separates the function header (everything between the def keyword and the colon) from the function’s body.

Docstring

The body starts with a docstring written between a set of two triple quotation marks. Docstrings are descriptions that programmers write for themselves or for other programmers to explain a function’s general purpose. 

Statements

Python functions require the function body to be written with a four-space indentation from the header. The body consists of several instructions that are executed each time the function is called. These are known as statements, and they can perform operations on the values that the function received as arguments. Upon the end of execution, a function, if instructed, will return a value using the return keyword at the end of its body.

Defining and Calling Python Functions

Now that we’ve seen a function definition prototype, let’s define our own function. We’ll use Python’s random module to create our function that generates a silly name by randomly choosing and combining elements from two lists.

A function definition specifies what the function will do when called, without executing it. We’ll use the following syntax to call the function:

Now, let’s call our function!

Default Parameters

Note how we didn’t provide any arguments to our function when we called it, however specifying two parameters in the function definition. When we make a call to a function, we’ll generally have to provide an argument for every parameter in the definition. However, when defining a function in Python, we’re able to specify default values for the parameters names and last_names if these otherwise lack arguments during a function call.

Alternatively, we’re able to provide our own arguments that’ll take precedence over the default values. In the code below, we’ll provide our function with a new set of arguments and generate cross-genre movie names.

The function works just the same, this time using the arguments that we passed to it.

Positional and Keyword Arguments

Python functions can accept two types of arguments: positional arguments and keyword arguments. 

When we called our function above, our provided arguments were implicitly assigned to the parameters based on the order in which they were defined. These arguments are known as positional arguments because they must be passed to the function in the correct position. If we were to reverse the argument order, the order of names and descriptions in the output would end up reversed as well.

We can also disregard the order by explicitly assigning the arguments to each parameter. This is done by using a keyword and equals sign, like below.

*args and **kwargs

If you don’t know in advance how many arguments you’ll be passing to the calling function, you could define a Python function that’ll accept a varying number of arguments. This is done with *args and **kwargs parameters.

*args allows you to pass a variable-length list of elements, and you’ll need to provide it after providing all positional arguments to the function call. **kwargs requires arguments to be keyworded, similar to a Python dictionary, and you’ll need to provide it at the end of a function call.

Below, we’ll extend our function to accept and print *args arguments.

We’ll provide our function with the names of the characters’ movies and TV shows. Although the names are passed to the function call as separate strings, the function packages them into the *args parameter, allowing us to iterate over and print them.

Note that using args and kwargs as parameter names is just a convention. In fact, you can use any names you like, so long as you use unpacking operators (* and **).

Recursive Functions

Many computer science problems are solved by dividing a given problem into smaller, simpler pieces. These pieces can in turn be broken down further until they’re so small as to result in a clear solution for each. These mini-solutions are finally combined to form the solution to the original problem.

This technique also applies to recursion. Recursive functions are those that repeatedly call themselves pending satisfaction of the condition that terminates the function. Each time the function is executed, it operates on a smaller subset of the values that it originally received as arguments, with each step greatly reducing the problem’s search space.

The function below is an example of a recursive function. Its argument specifies the number of times the function prints a greeting to the screen. This is achieved by the function’s recursive call to itself, with each call decrementing the argument by one. The condition that terminates the execution ensures that the function stops executing once the counter reaches zero.

Learn More

In this article, we took an in-depth look into the process of defining Python functions. But there’s much more you’ll need to learn about Python to start using it in real-world projects. Check out our Intro to Programming Nanodegree, a program that could very well be your first step towards careers in Web and App Development, Machine Learning, Data Science, AI, and more.

Start Learning