Working with functions

Functions are blocks of code logic that can be used multiple times within a program, simply by calling the function's name. If you don't use functions, but you want to repeat an operation multiple times, you will have to copy and paste the necessary code multiple times to get your program to work. If you ever have to revise the program, you would have to ensure that all applicable copied and pasted code is updated. With functions, a single code block can be updated. The following is an example of a function:

Function example

Preceding screenshot is about as simple as it gets. On line 1, we use the def keyword to define the function called square_num() (the parentheses indicate that it's a function rather than a statement) and tell it that the argument called x will be used for processing. Then we actually define what the function will do; in this case, it will multiply x by itself to produce a squared value. By using the return statement, the squared value will be returned back to whatever actually called the function (in this case, the print() function on line 2).

Next, on line 2, we create a for loop that iterates over a range of numbers, from 1 to 9; for each number, we call the square_num() function and then print the resultant squared value.

While this particular example was generated interactively in IPython, if you wanted to save this program to a file for later use, you would simply type the program into a text file, such as the following example, function_example.py:

def square_num(x): 
    return x * x 

for x in range(1, 10): 
    print(square_num(x))
 

To run the program, you first have to save it to your computer and give it a name ending in .py, for example, function_example.py. Then, on the command line, type python3 function_example.py. The results should look like following screenshot:

function_example.py output

Next we will talk about a neat little trick that demonstrates the power of Python: polymorphism. We touched on it in Chapter 2Data Types and Modules, in the Basic string operations section, but we'll discuss it in more depth here, as functions are one way to create polymorphism in your program.

The code in function_example.py shows that Python is capable of interpreting (to an extent) what you want to do. In this case, the * operator is overloaded to support multiple roles. If numbers are provided, it will multiply them; if a string and number is provided, it will perform repetition; and so on.

As long as the objects passed into a function support the intended action (as determined by the Python language), the function will process them. If a particular operation can't be performed on the objects passed in, the interpreter will return an error, letting the programmer know of the problem.

This feature is not generally found in static typed languages, such as C/C++. This is because static languages can only deal with data types that are explicitly stated; attempting to override the behavior won't work. You would have to create a function to perform repetition if you wanted to use the * operator, as it is used for number multiplication only. An example of polymorphism is displayed in following screenshot:

Polymorphism example

This little program is pretty powerful, as it takes a variable number of arguments and either adds them or concatenates (combines) them together, depending on the argument type. These arguments can be anything: numbers, strings, lists, tuples, and so on.

We mentioned the *args keyword previously in Chapter 2Data Types and Modules, in the String methods section. This is a special feature of Python that allows you to enter undesignated arguments and do things to them (such as add them together). The * is like a wildcard; it signifies that a variable number of arguments can be provided. You could get by without using the word args, but common practice is to include it for clarity.

A similar argument keyword is **kwargs. This one is related (it takes an unlimited number of arguments), but the arguments are set off by keywords.

This way, you can match variables to the arguments based on the keywords. *args and **kwargs can be used together, if desired.