Fundamentals » Defining Functions »

 

Defining Functions

Repetition Statements Table Of Contents Creating Modules


Functions in Python are equivalent to static or class methods in Java. The only difference is that they are not defined as part of a class. Instead, they are defined at the global-level and referenced by name alone or prefixed with a module name if defined within a module.

Python allows users to create user-defined functions that can be used to construct procedural programs. Functions allow for the subdivision of larger problems into smaller parts and efficient code reuse. In this chapter, we cover the creation of user-defined functions and assume the reader has experience writing static Java methods.

The Function Definition

A Python function contains a header and body. The function header is specified using the def keyword while the function body is specified as a statement block. The following function definition

def sumRange( first, last ) :
   total = 0
   i = first
   while i <= last :
      total = total + i
      i = i + 1
   return total
 

sums the range of values specified by the first and last arguments. A similar static method in Java would be written as

//Java method
public static int sumRange( int first, int last )
{
  int total = 0;
  int i = first;
  while( i <= last ) {
    total = total + i;
    i = i + 1;
  }
  return total;
}
 

A user-defined function is called like any other function in Python as illustrated in the following code segment

start = 1
end = 100
theSum = sumRange( start, end )
print "The sum of the integers between", start,\
      "and", end, "is", theSum
 

Function Arguments

Arguments in Python are passed by value and in the order specified. Since every value is an object, these values are always object references. The formal arguments defined for a function become aliases of the actual parameters passed to the function which it’s called.

Mutable Arguments

Passing the reference to a mutable argument to a function allows that object to be modified by the function. Immutable objects can not be modified within a function and is similar to passing Java primitive types “by value”.

Polymorphism

Python is a dynamically typed language with polymorphism everywhere. In fact, every operator in Python is a polymorphic operation. Polymorphism also plays a role with function arguments.

As you have noticed, data types are not specified for function arguments. So, what keeps us from passing floating-point values into the sumRange() function? Consider the following example

theSum = sumRange( 1.37, 15.78 )
 

which is a valid statement call in Python. So long as all operations within the function can be applied to the given values, the program will execute correctly. If an operation can not be applied to a given argument type, an exception will be raised to indicate the invalid type.

This flexability is a powerful feature of Python. It allows a single function to be applied to different object types without having to define multiple versions. To achieve the same flexability in Java, you would have to define the class and methods using generics which were introduced starting with Java version 1.5.

Default Values

Python allows functions to be defined with default argument values. For example, we can add a third argument to the sumRange() function to specify the step value.

def sumRange2( first, last, step = 1 ) :
   total = 0
   i = first
   while i <= last :
      total = total + i
      i = i + step
   return total
 

We have also provided a default value for the step argument. If the value of the third argument is omitted when calling the function as with the original function

theSum = sumRange2( 1, 100 )
 

the default value is assigned to the formal argument before the function is executed. If the value is supplied in the function call,

theSum = sumRange2( 1, 100, 2 )
 

that value is used instead. When definining functions with default arguments, you can not skip arguments. All arguments following the first one with a default value, must be assigned default valus. Otherwise, Python would have no way of knowing which argument is suppose to receive the default value. The function definition would be illegal since the second argument has a default value, but not the third one

def foo( argA, argB = 0, argC ) :
   print argA, argB, argC
 

Keyword Arguments

As in Java and most other languages, Python passes arguments to functions in the order they were specified. But Python also allows you to specify the argument order by using keyword arguments. Consider the following function call

theSum = sumRange2( last = 100, step = 3, first = 1 )
 

in which we directly specify which argument is suppose to receive which value.

Return Value

All functions in Python return a value whether you specify one or not. The return statement is used to terminate a function and return a value or more specifically to return an object reference. If you omit the return statement, Python automatically returns a reference to the None object.

Most functions return a single value, but you can define functions that return multiple values by returning those values within a tuple. The use of tuples is discussed in a later chapter.

Functions as Objects

While the def keyword is used to define a Python function, it is actually a statement which is executed by the interpreter. When Python executes a def statement, a function object is created containing the statments within the body of the function. The function name is actually a variable to which the function object is assigned as illustrated in the following diagram

The statements within a function are not executed until the function is called even though the statements are interpreted an converted to byte-code as they are read. Therefore, you can refer to one function within another before the former has been defined. Consider the following code segment

def run() :
  value = int( raw_input( "Enter a value: " ) )
  print "The double of your value is ", \
        doubleIt( value )

def doubleIt( num ) :
   return num * 2

run()
 

This is not the case, however, when calling a function from a statement at file level. For example, the function call in the following code segment is invalid because the interpreter does not know about the function at the time the function call is executed

callIt( 5 )

def callIt( num ) :
   return pow( num, 2 )
 

The order in which functions are listed within a file is not important, but the order of executable statements at file level is. Some people find it helpful to place the top-level statmentes within a single driver function and then call this function at the end of the file. Other functions used to subdivide the problem would be placed between the driver function and the call at the end of the file as illustrated in the following example.

Program: diceroll.py
#diceroll.py
#Simulate the rolling of two dice using the random
#number generator.

from random import *

# Minimum number of sides on a die
MIN_SIDES = 4

# Our very own main routine for a top-down design.
# This is not a standard function in Python.
def main() :
   print "Dice roll simulation."
   numSides = int(
       raw_input( "How many sides should the die have? " ) )
       
   if numSides < MIN_SIDES :
      numSides = MIN_SIDES
   value = rollDice( numSides )
   print "You rolled a", value
   
# Simulate the rollowing of two nSided dice.   
def rollDice( nSides ) :
   die1 = randint( 1, nSides + 1 )
   die2 = randint( 1, nSides + 1 )
   return die1 + die2
   
# Call the main routine which we difined as the first
# function in the file.
main()
 

Variable Scope

Variables are classified by their scope which indicates where the variable was created and where it can be used. Python has four scope classifications:

built-in
Variables and literal values defined as part of the language. These can be used anywhere within a program.
global or module
Variables created at the top-level of a source file or module (outside of all functions and classes). Unlike other languages in which a global variable can be used anywhere within a program, each module in Python creates its own global scope.
local
Variables created within a function are local to that function. Function and method arguments are local variables.
instance
Variables defined as data fields of a class.

Variables only exist within the scope in which they were created. The built-in and global scopes exist during the entire life of the program. Variables in the instance scope exist during the lifetime of the object for which they were defined. A local variable, however, only exist during the time in which the function is being executed. Each execution of a function, creates a new local scope which is then destroyed when the function terminates.

Referencing Global Variables

Global variables can be referenced within functions but local variables can not be referenced outside of their scope. Consider the following code segment

varA = 40

def one( varB ) :
   varC = varA + varB
   return varC

print varA, one( 20 )
 

varA and one are global variables since they are declared at the top-most or file level. varB and varC are local to the function and only exist when the function is executed. It is legal to reference variable varA from within one() since varA is a global variable. But what happens if we modify the function and assign a new value to varA?

varA = 40

def two( varB ) :
   varC = varA + varB
   varA = 0
   return varC

print varA, two( 20 )
 

A variable in Python can not be modified outside of the scope in which it was declared. Thus, the assignment of zero to varA within the function creates a new local variable with the same name as the global variable. The global variable varA is not modified, but it is used in the summation statement since that statement is executed before the local variable varA is created. The following diagram illustrates the variable statement at the end of the function but before it returns

Modifying Global Variables

To modify a global variable from within a function, you must use the global declaration which tells the Python interpreter to modify the global variable when it is assigned a new value instead of creating a new local variable.

varA = 40

def three( varB ) :
   global varA
   varC = varA + varB
   varA = 0
   return varC

print varA, three( 20 )
 

You can use a single global declaration to flag multiple variables, each separated with a comma

def foo() :
   global a, b, c
   a = b + c
   return a
 

Example Program



Repetition Statements Table Of Contents Creating Modules

© 2006 - 2008: Rance Necaise - Page last modified on August 26, 2006, at 04:39 PM