"Ordinary" Functions. Functions which follow the classic mathematical definitions map
input argument values to a resulting value. These are, perhaps, the most
common kind of functions, and don't have a special name. We'll look at
prodedure and factory functions which are atypical in that they may lack
a result or lack input values.
Procedure Functions. One common kind of function is one that doesn't return a result,
but instead carries out some procedure. This function would omit any
return
statement. Or, if
return
statements are used to exit from the function, they would have no value
to return. Carrying out an action is sometimes termed a side-effect of
the function. The primary effect is always the value returned.
Here's an example of a function that doesn't return a value, but
carries out a procedure.
def report( spin ):
"""Report the current spin."""
if spin == 0:
print "zero"
return
if odd(spin):
print spin, "odd"
return
print spin, "even"
This function, report
, has a parameter named
spin
, but doesn't return a value. Here, the
return
statements exit the function but don't return
values.
This kind of function would be used as if it was a new Python
language statement, for example:
for i in range(10):
report( random.randrange(37) )
Here we execute the report
function as if it
was a new kind of statement. We don't evaluate it as part of an
expression.
There's actually no real subtlety to this distinction. Any
expression can be used as a Python statement. A function call is an
expression, and an expression is a statement. This greatly simplifies
Python syntax. The docstring for a function will explain what kind of
value the function returns, or if the function doesn't return anything
useful.
The simple
return
statement, by the way, returns
the special value None
. This default value means that
you can define your function like report
, above, use
it in an expression, and everything works nicely because the function does
return a value.
for i in range(10):
t= report( random.randrange(37) )
print t
You'll see that t
is
None
.
Factory Functions. Another common form is a function that doesn't take a parameter.
This function is a factory which generates a value, often by accessing
some obscured object. Sometimes this object is encapsulated in a module
or class. In the following example, we'll access the random number
generator encapsulated in the random
module.
def spinWheel():
"""Return a string result from a roulette wheel spin."""
t= random.randrange(38)
if t == 37:
return "00"
return str(t)
This function's evaluate-apply cycle is simplified to just the apply
phase. To make 0 (zero) distinct from 00 (double zero), it returns a
string instead of a number.
Generators. A generator function contains the
yield
statement. These functions look like conventional functions, but they
have a different purpose in Python. We will examine this in detail in
Chapter 18, Generators and the
yield
Statement
.
These functions have a persistent internal processing state;
ordinary functions can't keep data around from any previous calls without
resorting to global variables. Further, these functions interact with the
for
statement. Finally, these functions don't make a
lot of sense until we've worked with sequences in Chapter 11, Sequences: Strings, Tuples and Lists
.