Functions are reusable pieces of programs. They allow you to give a
name to a block of statements, allowing you to run that block using
the specified name anywhere in your program and any number of
times. This is known as calling the function. We have already used
many built-in functions such as len
and range
.
The function concept is probably the most important building block of any non-trivial software (in any programming language), so we will explore various aspects of functions in this chapter.
Functions are defined using the def
keyword. After this keyword
comes an identifier name for the function, followed by a pair of
parentheses which may enclose some names of variables, and by the
final colon that ends the line. Next follows the block of statements
that are part of this function. An example will show that this is
actually very simple:
Example (save as function1.py
):
def sayHello():
print('Hello World!') # block belonging to the function
# End of function #
sayHello() # call the function
sayHello() # call the function again
Output:
$ python3 function1.py
Hello World!
Hello World!
How It Works:
We define a function called sayHello
using the syntax as explained
above. This function takes no parameters and hence there are no
variables declared in the parentheses. Parameters to functions are
just input to the function so that we can pass in different values to
it and get back corresponding results.
Notice that we can call the same function twice which means we do not have to write the same code again.
A function can take parameters, which are values you supply to the function so that the function can do something utilising those values. These parameters are just like variables except that the values of these variables are defined when we call the function and are already assigned values when the function runs.
Parameters are specified within the pair of parentheses in the function definition, separated by commas. When we call the function, we supply the values in the same way. Note the terminology used - the names given in the function definition are called parameters whereas the values you supply in the function call are called arguments.
Example (save as func_param.py
):
def printMax(a, b):
if a > b:
print(a, 'is maximum')
elif a == b:
print(a, 'is equal to', b)
else:
print(b, 'is maximum')
printMax(3, 4) # directly give literal values
x = 5
y = 7
printMax(x, y) # give variables as arguments
Output:
$ python3 func_param.py
4 is maximum
7 is maximum
How It Works:
Here, we define a function called printMax
that uses two parameters
called a
and b
. We find out the greater number using a simple
if..else
statement and then print the bigger number.
The first time we call the function printMax
, we directly supply the
numbers as arguments. In the second case, we call the function with
variables as arguments. printMax(x, y)
causes the value of argument
x
to be assigned to parameter a
and the value of argument y
to
be assigned to parameter b
. The printMax function works the same way
in both cases.
When you declare variables inside a function definition, they are not related in any way to other variables with the same names used outside the function - i.e. variable names are local to the function. This is called the scope of the variable. All variables have the scope of the block they are declared in starting from the point of definition of the name.
Example (save as func_local.py
):
x = 50
def func(x):
print('x is', x)
x = 2
print('Changed local x to', x)
func(x)
print('x is still', x)
Output:
$ python3 func_local.py
x is 50
Changed local x to 2
x is still 50
How It Works:
The first time that we print the value of the name x with the first line in the function's body, Python uses the value of the parameter declared in the main block, above the function definition.
Next, we assign the value 2
to x
. The name x
is local to our
function. So, when we change the value of x
in the function, the
x
defined in the main block remains unaffected.
With the last print
function call, we display the value of x
as
defined in the main block, thereby confirming that it is actually
unaffected by the local assignment within the previously called
function.
If you want to assign a value to a name defined at the top level of
the program (i.e. not inside any kind of scope such as functions or
classes), then you have to tell Python that the name is not local, but
it is global. We do this using the global
statement. It is
impossible to assign a value to a variable defined outside a function
without the global
statement.
You can use the values of such variables defined outside the function
(assuming there is no variable with the same name within the
function). However, this is not encouraged and should be avoided since
it becomes unclear to the reader of the program as to where that
variable's definition is. Using the global
statement makes it amply
clear that the variable is defined in an outermost block.
Example (save as func_global.py
):
x = 50
def func():
global x
print('x is', x)
x = 2
print('Changed global x to', x)
func()
print('Value of x is', x)
Output:
$ python3 func_global.py
x is 50
Changed global x to 2
Value of x is 2
How It Works:
The global
statement is used to declare that x
is a global
variable - hence, when we assign a value to x
inside the function,
that change is reflected when we use the value of x
in the main
block.
You can specify more than one global variable using the same global
statement e.g. global x, y, z
.
For some functions, you may want to make some parameters optional
and use default values in case the user does not want to provide
values for them. This is done with the help of default argument
values. You can specify default argument values for parameters by
appending to the parameter name in the function definition the
assignment operator (=
) followed by the default value.
Note that the default argument value should be a constant. More precisely, the default argument value should be immutable - this is explained in detail in later chapters. For now, just remember this.
Example (save as func_default.py
):
def say(message, times = 1):
print(message * times)
say('Hello')
say('World', 5)
Output:
$ python3 func_default.py
Hello
WorldWorldWorldWorldWorld
How It Works:
The function named say
is used to print a string as many times as
specified. If we don't supply a value, then by default, the string is
printed just once. We achieve this by specifying a default argument
value of 1
to the parameter times
.
In the first usage of say
, we supply only the string and it prints
the string once. In the second usage of say
, we supply both the
string and an argument 5
stating that we want to say the string
message 5 times.
Important
: Only those parameters which are at the end of the parameter list can
be given default argument values i.e. you cannot have a parameter with
a default argument value preceding a parameter without a default
argument value in the function's parameter list.
This is because the values are assigned to the parameters by
position. For example,`def func(a, b=5)` is valid, but `def
func(a=5, b)` is *not valid*.
If you have some functions with many parameters and you want to specify only some of them, then you can give values for such parameters by naming them - this is called keyword arguments - we use the name (keyword) instead of the position (which we have been using all along) to specify the arguments to the function.
There are two advantages - one, using the function is easier since we do not need to worry about the order of the arguments. Two, we can give values to only those parameters to which we want to, provided that the other parameters have default argument values.
Example (save as func_key.py
):
def func(a, b=5, c=10):
print('a is', a, 'and b is', b, 'and c is', c)
func(3, 7)
func(25, c=24)
func(c=50, a=100)
Output:
$ python3 func_key.py
a is 3 and b is 7 and c is 10
a is 25 and b is 5 and c is 24
a is 100 and b is 5 and c is 50
How It Works:
The function named func
has one parameter without a default argument
value, followed by two parameters with default argument values.
In the first usage, func(3, 7)
, the parameter a
gets the value
3
, the parameter b
gets the value 7
and c
gets the default
value of 10
.
In the second usage func(25, c=24)
, the variable a
gets the value
of 25 due to the position of the argument. Then, the parameter c
gets the value of 24
due to naming i.e. keyword arguments. The
variable b
gets the default value of 5
.
In the third usage func(c=50, a=100)
, we use keyword arguments for
all specified values. Notice that we are specifying the value for
parameter c
before that for a
even though a
is defined before
c
in the function definition.
Sometimes you might want to define a function that can take any
number of parameters, this can be achieved by using the stars (save as
total.py
):
def total(initial=5, *numbers, **keywords):
count = initial
for number in numbers:
count += number
for key in keywords:
count += keywords[key]
return count
print(total(10, 1, 2, 3, vegetables=50, fruits=100))
Output:
$ python3 total.py
166
How It Works:
When we declare a starred parameter such as *param
, then all the
positional arguments from that point till the end are collected as a
tuple called 'param'.
Similarly, when we declare a double-starred parameter such as
**param
, then all the keyword arguments from that point till the end
are collected as a dictionary called 'param'.
We will explore tuples and dictionaries in a later chapter.
If we want to specify certain keyword parameters to be available as
keyword-only and not as positional arguments, they can be declared
after a starred parameter (save as keyword_only.py
):
def total(initial=5, *numbers, extra_number):
count = initial
for number in numbers:
count += number
count += extra_number
print(count)
total(10, 1, 2, 3, extra_number=50)
total(10, 1, 2, 3)
# Raises error because we have not supplied a default argument value for 'extra_number' #
Output:
$ python3 keyword_only.py
66
Traceback (most recent call last):
File "keyword_only.py", line 12, in <module>
total(10, 1, 2, 3)
TypeError: total() needs keyword-only argument extra_number
How It Works:
Declaring parameters after a starred parameter results in keyword-only arguments. If these arguments are not supplied a default value, then calls to the function will raise an error if the keyword argument is not supplied, as seen above.
Notice the use of +=
which is a shortcut operator, so instead of
saying x = x + y
, you can say x += y
.
If you want to have keyword-only arguments but have no need for a
starred parameter, then simply use an empty star without using any
name such as def total(initial=5, *, extra_number)
.
The return
statement is used to return from a function i.e. break
out of the function. We can optionally return a value from the
function as well.
Example (save as func_return.py
):
def maximum(x, y):
if x > y:
return x
elif x == y:
return 'The numbers are equal'
else:
return y
print(maximum(2, 3))
Output:
$ python3 func_return.py
3
How It Works:
The maximum
function returns the maximum of the parameters, in this
case the numbers supplied to the function. It uses a simple if..else
statement to find the greater value and then returns that value.
Note that a return
statement without a value is equivalent to
return None
. None
is a special type in Python that represents
nothingness. For example, it is used to indicate that a variable has
no value if it has a value of None
.
Every function implicitly contains a return None
statement at the
end unless you have written your own return
statement. You can see
this by running print(someFunction())
where the function
someFunction
does not use the return
statement such as:
def someFunction():
pass
The pass
statement is used in Python to indicate an empty block of
statements.
Note
: There is a built-in function called max
that already implements
the 'find maximum' functionality, so use this built-in function
whenever possible.
Python has a nifty feature called documentation strings, usually referred to by its shorter name docstrings. DocStrings are an important tool that you should make use of since it helps to document the program better and makes it easier to understand. Amazingly, we can even get the docstring back from, say a function, when the program is actually running!
Example (save as func_doc.py
):
def printMax(x, y):
'''Prints the maximum of two numbers.
The two values must be integers.'''
x = int(x) # convert to integers, if possible
y = int(y)
if x > y:
print(x, 'is maximum')
else:
print(y, 'is maximum')
printMax(3, 5)
print(printMax.__doc__)
Output:
$ python3 func_doc.py
5 is maximum
Prints the maximum of two numbers.
The two values must be integers.
How It Works:
A string on the first logical line of a function is the docstring for that function. Note that DocStrings also apply to Modules and classes which we will learn about in the respective chapters.
The convention followed for a docstring is a multi-line string where the first line starts with a capital letter and ends with a dot. Then the second line is blank followed by any detailed explanation starting from the third line. You are strongly advised to follow this convention for all your docstrings for all your non-trivial functions.
We can access the docstring of the printMax
function using the
__doc__
(notice the double underscores) attribute (name belonging
to) of the function. Just remember that Python treats everything as
an object and this includes functions. We'll learn more about objects
in the chapter on classes.
If you have used help()
in Python, then you have already seen the
usage of docstrings! What it does is just fetch the __doc__
attribute of that function and displays it in a neat manner for
you. You can try it out on the function above - just include
help(printMax)
in your program. Remember to press the q
key to
exit help
.
Automated tools can retrieve the documentation from your program in
this manner. Therefore, I strongly recommend that you use docstrings
for any non-trivial function that you write. The pydoc
command that
comes with your Python distribution works similarly to help()
using
docstrings.
We have seen so many aspects of functions but note that we still haven't covered all aspects of them. However, we have already covered most of what you'll use regarding Python functions on an everyday basis.
Next, we will see how to use as well as create Python modules.