Home » Python Programming » Functions in Python

# Functions in Python

In this tutorial, I am going to discuss about functions in python, their importance and types of functions in python. We will also discuss user-defined functions in detail and scope and lifetime of variables in python.

## Functions in Python

Until now, we have seen different kind of datatypes in python, different statements which are used in flow of control of a program like if-else, for loop and while loop. We have also discussed about different built-in methods given by python for specific datatypes like for lists, strings, tuples, etc.

Functions in python are basically a block of statements which perform a certain task. We can call the function multiple times in a program, just like we can use len() function to get length of a string as many times as we want.

### Importance of functions

• Maximizing code reuse and minimizing redundancy : We can use functions many times in a program which maximizes the code reusing and we won’t have to write the same code again it also minimizes code redundancy.

• Organized code : As the functions are reusable to perform a specific task, it makes the program more modular and organized, so we can understand working of program in parts

### Types of Functions

There are different types of functions in python which can be used for different purposes. Let’s have a look at types of function :

1. Built-in Functions :

Built-in functions are python functions which are already provided by python which have their own purpose.

We have seen different built-in functions given specifically for each data type like : len(), type(), range() and others. These functions have already defined number of arguments and their return types.

2. User-defined Functions :

Python also provides a way for the user to create a function which can perform any task that they want. These are called as user-defined functions because user creates these functions and the user decides no. of arguments and parameters needed and return value of the function.

3. Anonymous functions :

Python also let’s user create anonymous functions which means that these functions have no name.

They are declared using lambda keyword, these functions only have a single statements although they can have multiple arguments/parameters and return one value after executing the statement.

## User-defined Functions

User-defined functions are the functions that are created by users to perform some specific as per their needs. User-defined functions helps in increasing the modularity of the program and makes it more understandable and easy to maintain.

A large program is divided in small segments which can be maintained more efficiently and by multiple people. User-defined functions also make the code less redundant.

### Defining a function

User-defined functions in python are declared using def keyword, they can have multiple arguments/parameters and return statements (but only one return statement is executed).

This function contain a block of statements which are executed every time the function is called.

Following is the basic syntax of a function definition in python :

def function_name(arguments):
''' doc string for the function'''
Block of statements to execute

return [expression]    

Let’s understand the above function definition with some points :

• The function is defined using def keyword followed by arguments or parameters enclosed within parenthesis. The block of the function is defined with help of indentation, as we know in python we define blocks using indentation.

• The second line in function declaration is a docstring. Docstring is similar to a multiline comment, it is used to write down the purpose and usage of the function. It is an optional statement, and used to increase readability of the program.

• After the docstring, a block of statements which we want to execute is written. This block is executed each time we call the function.

• The statement return [ expression ], is used to exit from the function. It either passes back an expression or a value. If we wish to return nothing from the function then we can use an empty return statement will return back None to the caller. The return statement is an optional statement, if the function does not return anything then we can simply not write a return statement.

Let’s have a look at a simple function definition and its working :

def add_me(val1, val2):
''' This python function takes two arguments and returns addition of the those values.'''
print("Values : ",val1,", ", val2)
result = val1 + val2
return result

The above function takes two values as argument and returns the addition of these values back to the caller. Here, we have used a variable to store and access the value which we want to return.

### Calling a function

Once the function is defined, it can be called from another function or anywhere in the program. To call the function we need to simply write the function name and give appropriate arguments in function.

out1 = add_me(8, 42)
print("Output from first call to function : ", out1)
print("Output from second call to function : ", out2)
print("Output from third call to function : ", out3)
Values :  8 ,  42
Output from first call to function :  50
Values :  Good ,   Morning
Output from second call to function :  Good Morning
Values :  [1, 2, 3] ,  [4, 5]
Output from third call to function :  [1, 2, 3, 4, 5]

### Docstring in a function

A docstring or documentation string is the first line after function header. It is used to explain the working of the function.

A docstring is an optional statement, but it is a good programming practice to document your code to make sure there is no useless code and each line has its own importance.

Docstring is generally enclosed within three single quotes and written immediately after the function header. If we wish to access docstring of a function, each function has an attribute __doc__ which will return the docstring of the function.

Let’s see how to get docstring of the function we just created :

print(add_me.__doc__)
 This python function takes two arguments and returns addition of the those values.

After docstring, a function contains a block of statements which are executed every time the function is called. These statements perform and accomplish task that we want using the function.

### Arguments and Parameters

Arguments : The values that are passed to functions are known as arguments.
Parameters : The values that the functions receive are termed as parameters.

The values that appear in a function call are arguments, and the values that are in the function header are parameters.

Arguments for a function can be of these types :

• literals
• variables
• expressions

But parameters should be identifiers which are variables to hold the values received from the function call.

Let’s see some examples :

def multiply(a, b): #a and b are parameters i.e identifiers which hold received values.
print(a, "*", b, " = ", a * b)

multiply(2,5)  #both arguments are literals.
v1 = 8
v2 = 3
multiply(v1, v2) #both arguments are variables.
multiply(v1, v1+3)  #one argument is variable and one is an expression.
2 * 5  =  10
8 * 3  =  24
8 * 11  =  88

We will discuss about arguments and parameters in detail in upcoming tutorials.

### Return Statement

Return statement in python is used to exit from a function, it takes the program control from the function and returns it back to the line where the function is called.

A return statement can have a expression or a value which is returned to the function call in the main program. The expression is evaluated and result is sent back to the function call.

If we do not wish to return anything from the function, then we can either write simple return without any value or no return statement. In both the cases function call will be having None as a result.

Let’s have a look at some examples :

# Function with no return statement
def func1(line):
''' This function simple prints the argument received.'''
print(line)

# Function with expression in return statement
def func2(x,y):
''' This function returns result of an expression invoving two variables form the arguments.'''
return 5*x + 3*y +10

# Function with simple value in return statement
def func3(value):
'''This function returns square of the value from the argument'''
square = value ** 2
return square

# Function with empty return statement
def func4(name, greeting):
print("Hello {}, {}".format(name, greeting))
return

As you can see we have created four different functions, with different arguments and return values. Now, let’s see what do we get when we call these functions.

print("Function 1 : ",func1("Coding is fun"))
print("\n")
print("Function 2 : ",func2(9,4))
print("\n")
print("Function 3 : ",func3(6))
print("\n")
print("Function 4 : ",func4("John","How are you today ?"))
Coding is fun
Function 1 :  None

Function 2 :  67

Function 3 :  36

Hello John, How are you today ?
Function 4 :  None

Observe that for return statement with expression, the function returns the result from the evaluated expression,for no return statement or empty return statement, we get None object from the function.

## Scope and Lifetime of Variables

### Scope of variables

Scope of a variable in a language is defined as the part of code in which that variable is active or can be used. Variables declared inside a block of code have the scope within that block, i.e. they are not accessible outside that block.

Here block can mean an if-else block, for or while loop block or a function block. Such kind of variables are said to have a local scope i.e. scope within the block.

The variables which are declared in the main program and outside of every block, can be accessed from any block throughout the program. Such kind of variables are said to have global scope i.e can be accessed globally throughout the program.

Let’s see some examples to understand concept of scope :

power = 3
def raise_me():
var = 5
result = var ** power
return result

print("Result from function : ", raise_me())
print("power : ", power)
print("var : ",var, ", result : ",result)
Result from function :  125
power :  3

---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

in
7 print("Result from function : ", raise_me())
8 print("power : ", power)
----> 9 print("var : ",var, ", result : ",result)

NameError: name 'var' is not defined

Following points can be observed from the above example :

• var and result are variables having local scope within the raise_me() function. That is why these variables cannot be accessed outside the raise_me() function.

• power variable have global scope which means it is accessible throughout the program.

Lifetime of a variable means the time till which the variable is active or lives in the memory. As you can see in the above example, the variables var and result are not accessible outside the raise_me() function.

Lifetime of these variables ends when the function stops executing, which is why they are inaccessible. Lifetime of a variable is limited to lifetime of the block in which the variable is working. On contrary to these two variables, the power variable is accessible throughout the program which means that it has a lifetime until the program ends.

The variables having limited scope are destroyed after the block in which they are defined stops executing. And every time the block is executed these variables are created again.

Let’s see the below example :

def lifetime():
var = 80
print("Value inside the function : ", var )

var = 40
print("Value outside the function : ",var)

Value outside the function :  40
Value inside the function :  80