Newby Coder header banner

Python Functions

What is a function in Python?

A function is a block of organized, reusable code/statements that is used to perform a specific, related task

As a program grows larger, functions make it more organized and manageable

Furthermore, it avoids repetition and makes code reusable

Types of Functions

Basically, functions can be divided into the following two types:

  1. Built-in functions - Functions that are built into Python
  2. User-defined functions - Functions defined by the users themselves

Defining a Function

Defining a function gives it a name, specifies the parameters that are to be included in the function and structures the blocks of code

Syntax of Function

def function_name( parameters ):
    """docstring"""
   statement(s)
   return [expression] 

Parameters have a positional behavior and are supposed to be passed in the same order as they were defined, unless their keywords are provided (see Keyword arguments)

Example

The following function takes a string as input parameter and prints it on console (terminal screen)

def print_str(string):
    "This prints the string passed into this function"
    print(string)
    return 

THe print() function prints (displays) any string(s), passed to it as parameter(s), on the screen

Calling a function in Python

Once a function is defined, it can be called from another function, program or from the Python prompt

To call a function, the function name is typed along parentheses (with parameters inside, if present)

Example

def print_function():
        print("Hello from a function")
print_function() 

Following example defines and calls print_str() function

#!/usr/bin/python
# Function definition
def print_str( string ):
    "This prints a passed string into this function"
    print(string)
    return

# Now print_str function can be called
print_str("First call to user defined print_str function ")
print_str("Second call to the same function") 

Assuming the above code is saved in a file program.py, it can be executed to produce following output :

$ python program.py
First call to user defined print_str function
Second call to the same function 

return Statement

return statement is used to exit a function and go back to the place from where it was called

The statement return [expression] exits a function, optionally passing back an expression to the caller

If there is no expression in the statement or if the return statement is not present inside a function, then the function returns None object

Syntax of return

return [expression_list] 

This statement can contain expression which gets evaluated and the value is returned

Example

A value can be returned from a function as follows :

#!/usr/bin/python
# Function definition is here
def sum(arg1, arg2 ):
    """ Return sum of parameters passed"""
    return arg1 + arg2

# Now sum function can be called to retrieve sum of numbers passed as parameters
print(sum(10, 20))
print(sum(-100, 20)) 

When above code is executed, it produces following output:

30
-80 

Function Arguments

Information can be passed to functions as parameter

A function can be defined to take multiple parameters as input, separated by comma

Parameters are specified after the function name, inside the parentheses

Example

The following example has a function with one parameter - fn

When the function is called, a string denoting a first name is passed, which is used inside the function to print the full name :

def print_name(fn):
    print(fn + " Nerfit")
print_name("Erik") print_name("Botisa") print_name("Linus")

Output :

Erik Nerfit
Botisa Nerfit
Linus Nerfit 

Unlike some languages, there is no requirement to mention the type of argument (like string, integer), since Python handles it dynamically

A function can be called by using following types of formal arguments

Required arguments

Required arguments are the arguments passed to a function in the same positional order as that of function definition

The number of arguments in the function call should contain all required arguments

To call function printme(), one argument has to be passed, otherwise it gives a syntax error as follows :

#!/usr/bin/python
# Function definition is here
def printme( str ):
    "This prints a passed string into this function"
    print(str)
    return

# Now you can call printme function
printme() 

When above code is executed, it produces following output :

Traceback (most recent call last):
   File "test.py", line 11, in <module>
      printme();
TypeError: printme() takes exactly 1 argument (0 given) 

Default arguments

A Function can have a default value associated with a parameter

If the function is called without any value for that parameter, then it uses the default value

Example

def is_integer(number = 0):
    if (type(number) == int):
        print(number, " is an integer")
    else:
        print(number, " is not an integer")
is_integer(10)
is_integer()
is_integer(0.1) 

Output

10 is an integer
0 is an integer
0.1 is not an integer 

Python Kwargs : Variable-length arguments

A function might be required to accept additional arguments than the default arguments

These arguments are called variable-length arguments and are not named in the function definition, unlike required and default arguments

Syntax for a function with non-keyword variable arguments is as follows :

def function_name([formal_args,] *var_args_tuple ):
   "function_docstring"
   function_code
   return [expression] 

An asterisk (*) is placed before the variable name that holds the values of all non-keyword variable arguments

This tuple remains empty if no additional arguments are specified during the function call

Following is a simple example :

#!/usr/bin/python
# Function to print variable length arguments is defined
def print_args(arg1, *vartuple):
    print("arg1 is: ", arg1)
    print("tuple is: ", vartuple)
    return

# Now you can call print_args function
print("Function call with 10 as argument")
print_args(10)
print("Function call with 70, 60, 50 as arguments")
print_args(70,60,50) 

When the above code is executed, it produces the following output:

Function call with 10 as argument
arg1 is: 10
tuple is: None
Function call with 70, 60, 50 as arguments
arg1 is: 70
tuple is: (60, 50) 

Keyword arguments

Functions can be called by using parameter names as keywords to assign values to the arguments during function call itself

This allows you to skip (default) arguments or place them out of order while calling a function

Example to call print_args function by using parameter names name and age to assign their values

#!/usr/bin/python
# Function definition is here
def print_args( name, age ):
    "This prints a passed info into this function"
    print("Name: ", name)
    print("Age ", age)
    return

# Now you can call print_args function
print_args( age=50, name="miki") 

When above code is executed, it produces following output:

Name:  miki
Age  50 

Passing a List as a Parameter

Functions accept lists as parameter

Example

Following example defines a function which takes a list as a parameter, and prints each element of the list :

def print_function(food_list):
    for x in food_list:
        print(x)
dinner = ["whisky", "peanuts", "pepper"]
print_function(dinner) 

Output :

whisky
peanuts
pepper 
Values of any data type can be sent to a function (string, number, list, dictionary etc.) for any parameter, since there is no type checking

A string can also be passed to the function mentioned above :

def print_function(food_list):
    for x in food_list:
        print(x)
dinner = "bullet"
print_function(dinner) 

Output :

b
u
l
l
e
t 

This worked since strings can be iterated upon

The function can be called with a number, in which case the iteration code throws exception

Pass by reference vs Pass by value

All parameters (arguments) in Python are passed by reference

Thus, if value of a python object is altered within a function, then the change also gets reflected outside the function

This happens until the object is assigned to another value within the function (since the reference is overwritten and the object loses its initial reference, within the function)

For example :

#!/usr/bin/python
# Define function which alters data
def alter_data(input_list):
    input_list.append([1,2,3,4]);
    print("Value of list inside alter_data() function: ", input_list)
    return

# A list is initialized
example_list = [10,20,30]
# alter_data function can be called on the list, which appends data and prints the updated list inside the function
alter_data(example_list)
print("Value of list outside: ", example_list)

# Define function which updates the list passed as argument, assigns it to a new list and then updates the new list
def change_reference(input_list):
    input_list.append(5);
    input_list = [11, 14, 18]
    input_list.append(25);
    print("Value of list inside change_reference() function: ", input_list)
    return

change_reference(example_list)
print("Value of list outside, after change_reference() function: ", example_list) 

This should produce the following output when executed :

Value of list inside alter_data() function:  [10, 20, 30, [1, 2, 3, 4]]
Value of list outside:  [10, 20, 30, [1, 2, 3, 4]]
Value of list inside change_reference() function:  [11, 14, 18, 25]
Value of list outside, after change_reference() function:  [10, 20, 30, [1, 2, 3, 4], 5] 

Scope and Lifetime of variables

Scope of a variable is the portion of a program where the variable is recognized and accessible

Parameters and variables defined inside a function is not visible from outside, and hence, they have a local scope

Lifetime of a variable is the period throughout which the variable exits in the memory

The lifetime of variables inside a function is as long as the function executes, and are destroyed after execution

Example

Example to illustrate the scope of a variable inside a function :


x = 30
function change_value():
    x = 20
    print("Value of x inside function: ", x)
change_value()
print("Value of x outside function: ", x) 

Output :

Value of x inside function: 20
Value of x outside function: 30 

Here, even though the function change_value() changed the value of x to 20, it did not effect the value outside the function

This is because the variable x inside the function is different (local to the function) from the one outside, although they have same names

Variables outside of the function have a global scope and are visible from inside, where they can be read but not changed

Example

x = 30
function print_value():
    print("Value of x inside function : ", x)
print_value()
print("Value of x outside function: ", x)
x = 50
print_value() 

Output :

Value of x inside function: 30
Value of x outside function: 30
Value of x inside function: 50 

In order to modify the value of variables declared outside the function, they must be declared as global variables inside a function, using the keyword global

Recursive Function

A recursive function is one which calls itself

Example
# Define a recursive function to return the factorial of a number
def factorial(n):
    if n > 1:
        return n * factorial(n-1)
    else:
        return 1

# print factorial of 10
print(factorial(10)) 
Output
3628800 

The Anonymous Functions

These functions are called anonymous because they are not declared in the standard manner by using the def keyword

Instead, the lambda keyword is used to create small anonymous functions

lamda functions are assigned to a variable which can then be called as a function

Syntax

The syntax of lambda functions contains only a single statement, which is as follows -

lambda [arg1 [,arg2,.....argn]]: expression 

Following example shows how lambda form of function works :

#!/usr/bin/python
# Function definition is here
sum = lambda arg1, arg2: arg1 + arg2;

# Now you can call sum as a function
print("Value of total : ", sum(10,20))
print("Value of total : ", sum(20,20)) 

When the above code is executed, it produces the following output :

Value of total :  30
Value of total :  40 
ⓘ More about lambda

Docstring

The first string after the function header is called the docstring and is short for documentation string

It is used to explain in brief, what a function does

Although optional, documentation is considered a good programming practice

Generally triple quotes are used so that docstring can extend up to multiple lines

This string can be accessed with __doc__ attribute of a function

For example:

Try running the following into the Python shell to see the output


def str_length(string):
    """This function returns the length of string passed as parameter"""
    return len(string)

print(str_length.__doc__) 

Output

This function greets to the person passed into the name parameter