Functions in Python

So far in this course, we have been using built-in functions that come with Python. In this lesson, we will learn how we can create our own functions. But before we do that, let’s spend some time learning why we even need them in the first place.

Suppose you want to create a program which allows users to calculate the sum between two numbers. At this point, you shouldn’t have any problem writing such programs; anyway, your code might look this:

This program calculates the sum of all numbers from 10 to 30. If we want to calculate the sum of numbers from 100 to 200, we would need to update the program as follows:

As you can see both versions of the program is nearly identical, the only difference is in the values of the start and end variables. So everytime we want to calculate the sum of two numbers, we would need to update the source of the program. It would be good if we somehow just reuse the entire code without doing any modification. We can do that using functions.

What is a Function?

A function is named group of statements, which perform a specific task. The syntax of defining a function is as follows:

A function consists of two parts: header and body. The function header starts with the def keyword, followed by name of the function, followed by arguments and ends with a colon (:).

The def is a reserved keyword, so you shouldn’t use it as a variable or function name in your programs. function_name can be any valid identifier. After the function name, we have a list of arguments inside parentheses separated by a comma (,). We use these arguments to pass the necessary data to the function. A function can take any number of arguments or none at all. If a function doesn’t accept any argument then the parentheses is left empty.

In the next line, we have a block of statements or function body. The function body contains statements which define what the function does. As usual, Python uses indentation of statements to determine when block starts and ends. All the statements in the body of the function must be equally indented otherwise you will get a syntax error.

Pay special attention to the last statement in the function body i.e <return statement>. The return statement is used to return a value from the function. The return statement is not mandatory, some function return values while others don’t. If a function doesn’t have return statement in the body then a reserved keyword None is returned automatically. None is actually an object of a built-in type NoneType. Don’t worry if you find return statement confusing; they are not, we will discuss return statement in detail in the upcoming section.

Here is a small function which prints current date and time along with a greeting:


The greet() function doesn’t accept any arguments, that’s why parentheses are left empty. The function body contains two print() statements. These two statements will be executed when we call greet() function. The greet() function doesn’t return any value.

Function Call

A function definition does nothing by itself. To use a function we must call it. The syntax of calling a function is as follows:

If a function doesn’t accept any arguments then use the following syntax:

The following code calls greet() function:



The function call must appear after the function is defined otherwise, you will encounter NameError exception. For example:



When a function is called the program control jumps to that function definition and executes the statements inside the function body. After executing the body of the function, the program control jumps back to the part of the program which called the function and resumes execution at that point.

The following example demonstrates what happens when a function is called.



In lines 3-5, we have defined a greet() function. The print() statement in line 7, prints string "Before calling greet()" to the console. In line 8, we are calling greet() function. At this point, the execution of statements following the call to greet() halts and program control jumps to the definition of the greet() function. After executing the body of the greet() function program control again jumps back to the point where it left off and resumes the execution from there.

transfer of control

Our previous program has only function. It is not unusual for programs to have hundreds or even thousands of functions. In python, it a common convention to define a function called main() which gets called when the program start. This main() function then goes on to call other function as needed. The following program demonstrates the flow of program control when we have two functions in a program.


In lines 3-5, and 7-10, we have defined two functions greet() and main(). The greet() function is now updated to accept an argument called name, which it then uses in the next line to greet the user.

The main() function doesn’t accept any arguments and has three statements inside the body.

The statement in line 12, calls the main() function. The program control jumps to the body of the main() function. The first statement inside the main() prints string "main() function called" to the console. The statement in line 9, calls the greet() function with an argument "Jon" which will be assigned to the variable name in the function header. At this point, execution of statements following the call to greet() halts and program control jumps to the body of the greet() function. After executing the body of the greet() function, program control jumps back to where it left off and executes the print() statement in line 10. As there are no more statements left to execute in the main() function and program control jump again back to where it left off to execute statements after the function call (line 12).

Local Variables, Global Variables and Scope

Variable Scope: The scope of a variable refers to the part of the program where it can be accessed.

The variable we create inside the function is called a local variable. Local variables can only be accessed inside the body of the function in which it is defined. In other words, the scope of a local variable starts from the point they are defined and continues on until the end of the function. Local variables are subject to garbage collection as soon as the function ends. As a result, trying to access a local variable outside of its scope will result in an error.

On the other end of the spectrum, we have Global variables. The Global variables are variables that are defined outside of any functions. The scope of a global variable starts from the point they are defined and continues on until the program ends.

Now consider the following examples:

Example 1:



In line 1, we have created a global variable named global_var. It is then accessed in line 12, inside the func() function and in line 16, outside the function. We have also declared a local variable named local_var inside the function func(). It is then accessed inside the function in line 9.

Let’s see what happens, if we try to access a local variable outside the function. To do so, uncomment the code in line 18 and run the program again.


The error NameError: name 'local_var' is not defined tells us that there is no variable named local_var exists in this scope.

What if we have local and global variables of the same name? Consider the following program.

Example 2:



Here we have a global variable num in line 1 and a local variable of the same name inside the function in line 4. Whenever there is a conflict between a local and global variable inside the function, the local variable gets the precedence. This is the reason why print() function (line 5) prints the value of the local num variable. However, outside the function, num refers to the global num variable.

We can also use the same variable names in different function without conflicting with each other.



Passing Arguments

An argument is nothing but a piece of data passed to the function, when it is called. As said before, a function can take any number of arguments or none at all. For example, print() function accepts one or more arguments but random.random() function accepts none.

If you want a function to receive arguments, when it is called, we must first define one or more parameters. A parameter or parameter variable is simply a variable in the function header which receives an argument when the function is called. Just like local variables, the scope of parameter variables is only limited to the body of the function. Here is an example of a function which accepts a single argument:

When function add_100() is called with an argument, the value of the argument is assigned to the variable num and the print() statement prints the value of num after adding 100 to it.

The following program demonstrates how to call a function with an argument.



In line 5, function add_100() is called with an argument 100. The value of the argument is then assigned to the parameter variable num.

Example 2: Function to calculate the factorial of a number.



The factorial of a number n is defined as multiplication of all digits from 1 to n.

where n! denotes factorial of n. Here are some examples:

Now, let’s see how the for loop works when the value of n is 4:

Before for loop starts i not defined f = 1 n = 4
After 1st iteration i = 4 f = n * f = 4 * 1 = 4 n = 3
After 2nd iteration i = 3 f = n * f = 3 * 4 = 12 n = 2
After 3rd iteration i = 2 f = n * f = 2 * 12 = 24 n = 1
After 4th iteration i = 1 f = n * f = 1 * 24 = 24 n = 0

After the 4th iteration loop terminates and print() function prints the factorial of the number.

Example 3: Passing multiple arguments to the function



When calc() function is called in line 8, the argument 10 is passed to parameter variable num1 and 20 is passed to parameter variable num2.

The order of arguments passed while calling the function must match the order of parameters in the function header, otherwise, you may get unexpected results.

Pass by Value

Recall that everything in Python is an object. So a variable for an object, is actually a reference to the object. In other words, a variable stores the address where an object is stored in the memory. It doesn’t contain the actual object itself.

When a function is called with arguments, it is the address of the object stored in the argument is passed to the parameter variable. However, just for the sake of simplicity, we say the value of an argument is passed to the parameter while invoking the function. This mechanism is known as Pass By Value. Consider the following example:


Notice that the id values are same. This means that variable arg1 and para1 references the same object. In other words, both arg1 and para1 points to the same memory location where int object (100) is stored.

arg1 and para1 references the same object

This behavior has two important consequences:

  1. If arguments passed to function is immutable, then the changes made to the parameter variable will not affect the argument.
  2. However, if the argument passed to the function is mutable, then the changes made to the parameter variable will affect the argument.

Let’s examine this behavior by taking some examples:

Example 1: Passing immutable objects to function.



In line 7, func() is called with an argument arg1 (which points to an immutable object int). The value of arg1 is passed to the parameter para1. Inside the function value of para1 is incremented by 100 (line 2). When the function ends, the print statement in line 8 is executed and the string "After function call, arg1 = 100" is printed to the console. This proves the point that no matter what function does to para1, the value of arg1 remains the same.

If you think about it this behavior makes perfect sense. Recall that the contents of immutable objects can’t be changed. So whenever we assign a new integer value to a variable we are essentially creating a complete new int object and at the same time assigning the reference of the new object to the variable. This is exactly what’s happening inside the func() function.

Example 2: Passing mutable objects to function



The code is almost the same, but here we are passing a list to the function instead of an integer. As the list is a mutable object, consequently changes made by the func() function in line 2, affects the object pointed to by variable arg1.

Positional and Keyword Arguments

Arguments to a function can be passed in two ways:

  1. Positional argument.
  2. Keyword argument.

In the first method, we pass arguments to a function in the same order as their respective parameters in the function header. We have been using this method to pass arguments to our functions. For example:


The statement is_pythagorean_triplet(3, 4, 5) passes 3 to base, 4 to height and 5 to perpendicular, and prints "Numbers passed are Pythagorean Triplets". However, the statement is_pythagorean_triplet(3, 5, 4), passes 3 to base, 5 to height and 4 to perpendicular and prints "Numbers passed are not Pythagorean Triplets", which is wrong. So when using positional arguments always make sure that order of arguments in function call and order of parameters in function header matches. Otherwise, you may get expected results.

The other way to pass arguments to a function is to use Keyword arguments. In this method we pass each argument in the following form:

where parameter_name is the name of the parameter variable in the function header and val refers to the value you want to pass to the parameter variable. Because, we are associating parameter name with values, the order of arguments in the function call doesn’t matter.

Here are some different ways in which we can call is_pythagorean_triplet() function using keyword arguments:

Keyword arguments are a little bit flexible because we don’t have to remember the order of parameters in the function header.

Mixing Positional and Keyword arguments

We can also mix positional arguments and keyword arguments in a function call. In doing so, the only requirement is that positional arguments must appear before any keyword arguments. It means that the following two calls are perfectly valid because in both calls positional arguments are appearing before keyword arguments.

However, we can’t do this:

The problem here is that the positional argument (5) is appearing after the keyword argument (height=4). Trying to call is_pythagorean_triplet() in this way results in the following error:

Returning Values

Up to this point, we have been creating functions which don’t return any values, such functions are also known as void functions.

To return value from a function we use return statement. It’s syntax is:

The square brackets ([]) around the expression indicates that it is optional. If omitted a special value None is returned.

When return statement is encountered inside a function, the function terminates and the value of the expression followed by the return keyword is sent back to the part of the program that called the function. The return statement can appear anywhere in the body of the function. The functions which returns values are known as value-returning functions.

Here is an example:

A function can be called in two ways, depending upon whether they return value or not.

If a function returns a value then a call to such a function can be used as an operand in any expression in the program. For example:

In the above expression, we are first calling the add() function, and then assigning the return value of the function to the result variable. Had we not used the return statement in the add() function, we wouldn’t be able to write this code. Here are some other ways in which we can call add() function.

We are not bound to use the return value from the function. If we don’t want to use the return value, just call the function as a statement. For example:

In this case, the return value of add() is simply discarded.

Let’s rewrite our factorial program to return the factorial instead of printing it.



In the above example, we are returning an integer value from the function, but we can use any type of data int, float, str, bool; you name it. The following program demonstrates how to return bool type from the function:


1st run Output:

2nd run Output:

If expression followed by return keyword is omitted then a special value None is returned.



We can also use return statement multiple times inside the function but as soon as the first return statement is encountered the function terminates and all the statements following it are not executed. For example:


First run output:

Second run output:

Void Function returns None

In Python, void functions are slightly different than functions found in C, C++ or Java. If the function body doesn’t have any return statement then a special value None is returned when the function terminates. In Python, None is a literal of type NoneType which used to denote the absence of a value. It is commonly assigned to a variable to indicate that the variable does not points to any object.

The following program demonstrates that the void functions return None.



Sure enough! add() function indeed returns None. So we can say that in Python, all functions return value whether you use return statement or not. However, this doesn’t mean that you can use void functions just like a value-returning function. Consider the following example:



In line 4, we are trying to add value returned from add() i.e None to the integer 100, but the operation failed because + operation can’t add NoneType to int.

That’s why a void function is generally invoked as a statement like this:

Returning Multiple Values

To return multiple values from a function just specify each value separated by a comma (,) after the return keyword.

When calling a function returning multiple values, the number of variables on the left side of = operator must be equal to the number of values returned by the return statement. So if a function returns two values then you must use 2 variables on the left side of = operator. Here is an example:



Notice how values are assigned while calling the function. The statement:

assigns the smaller number to variable number1 and greater number to variable number2.

Default Arguments

In Python, we can define a function with default parameter values, this default value will be used when a function is invoked without any argument. To specify a default value for the parameter just specify the value using the assignment operator followed by parameter name. Consider the following example:



In line 7, we are calling function calc_area() without any arguments, so default values 2 and 3 will be assigned to length and width parameters respectively.

In line 8, we are calling calc_area() by passing 4 to length and 6 to width. As values to both the parameters are provided while calling the function, the default value will not be used in this case. The same is true for calc_area() call in line 9, except here we are using keyword arguments.

In line 10, we are only providing value to length parameter using keyword argument, as a result, the default value for width parameter will be used.

2 thoughts on “Functions in Python

  1. “The statement is_pythagorean_triplet(3, 4, 5) passes 3 to base, 4 to height and 5 to base, and prints ”

    I believe there is an error here. 5 is being passed to perpendicular and not base

Leave a Comment

%d bloggers like this: