A function is simply a section of code that can be called multiple times and from multiple locations. We have already used a number of built-in functions that are part of the Python language such as: float(), int(), lower(), str(), upper(). In this chapter we begin to work with functions that we write ourselves (a.k.a. programmer-defined functions).
Benefits of Functions
Functions provide the following benefits:
- Modularity - Functions provide a way for developers to modularize code. By modularizing, developers obtain the benefits of improved designs and implementations.
- Reuse - Developers can call functions multiple times and from multiple locations within the same program. Developers can also import modules containing functions that can be reused by multiple programs.
- Reduce Duplication - Since the same function can be called (used) multiple times, there is no need for the same code to appear in multiple locations.
- Maintainability - It is much easier to maintain code that has been modularized using functions. The alternative to functions is having the code in larger, interrelated segments that are difficult to design, debug, and maintain.
- Information Hiding - The details of function internals are hidden to the callers of the functions. The callers just need to know the contract (or interface agreement) to use the function. That is, what arguments should be passed to the function and what data is expected for the function to return.
Attributes of Functions
Functions have the following attributes. These attributes are demonstrated in the two code examples below.
- Definition of Functions - Functions in Python are defined with the keyword def and can be named using the identifier naming rules.
- Function Naming Rules - Function identifiers follow the Python identifier naming rules.
- Function Naming Conventions - follow the naming convention of all lower case with words separated by underscores.
- Function Identifiers - are usually action-based since functions perform actions (e.g. set_id(), get_name(), calculate_area() are all action-based names).
- Calling Functions - Functions are called (invoked) by using the function name followed by parentheses. For instance, 'execute_query()' calls or invokes the 'execute_query()' function.
- Argument Passing - Objects can be passed to functions via a parameter list in the function. For instance, in the line 'def calculate_sphere_volume(radius)' radius is a parameter in the function parameter list. A parameter receives a value from an argument when the function is called. Arguments are passed to functions when the function is called by a line like 'calculate_sphere_volume(33)'. The number 33 is an argument in the function call argument list.
- Immutable Argument - (e.g. numeric literal, string, tuple) passed to a function will not be changed in the caller.
- Mutable Argument - passed to a function will be changed in the caller if it is changed in the called function. However, if a copy of the mutable argument is passed to the called function then the change made in the called function will not be seen in the caller.
- Multiple Parameters - If a function has multiple parameters in the function definition, then the same number of arguments should be in the call to the function.
- Keyword Arguments - Functions can be called with keyword arguments which use the same names in the argument list as those in the parameter list. When using keyword arguments, the arguments do not have to be in the same order as the parameters.
- Local Variables - Variables created inside a function have scope which is local to that function. This means that those variables are not visible and cannot be used outside of that function.
- Global Variables - Variables created outside of all functions have module-level ( global) scope and are visible to all code in that module. Any function within the module can access the global variables.
- Global Keyword - To change global variables within a function use the global keyword within the function.
- Shadow Variables - If the global keyword is not used within the function, the function local variables with the same name as global variables will shadow the global variables and will be local to the function.
Here's the first of two code examples in this chapter. As always, be sure to code the example and work with variations of your own to ensure understanding of the concepts covered.
By the way, both code examples contain lines like that shown in the code from line 151 to 160. The purpose of that 'if statement' is to determine if the file containing this code (functions_0.py) is being run as the main program. If it is being run as the main program the module attribute '__name__' will be set to 'main'. If that is the case, the 'main()' function will be called and the program will process beginning with the main() function. If the file is not running as the main program, it is being imported as a module in which case the functions in the file will be called later by the program that imported this file. We will cover more about importing modules in an upcoming chapter.
Here's the output of functions_0.py.
Here's the code for the second set of function examples.
Here's the output of functions_1.py