What is modular programming?
Modular programming is a design principle that allows complex unit to be broken into smaller, more manageable pieces. Breaking down complex system into smaller units has several benefits:
- Effective reusability - The same function when needed in several parts of the application could be effectively reused.
- Code readability - Typical medium to large size project could have thousands of lines of code. Without modularity, it is very hard to read and maintain the application.
- Division of responsibility - Applications with modules could be effectively developed independently by more than one developer.
- Effective debugging - It is easier to spot and fix bugs when the codebase is broken into modules.
How to create modules in Python?
Writing modules in Python is straight forward. Every file written in Python with a .py extension is considered a module. So, there is no special keyword to create modules in Python.
Here is a simple python module called hello.py containing two functions that prints hello or goodbye several times depending on the argument passed:
def say_hello(times): print(“Hello!\n”*times)) def say_bye(times): print(“Goodbye!\n”*times))
How to reuse modules?
Functions defined in the
hello module should be first imported before it can be called from another part of the application.
import hello #Say hello 10 times hello.say_hello(10)
Note that import statements can be placed anywhere in the Python file. But it is a good practice to place all of the imports on top of the file.
What is a direct import?
Modules could also be imported directly using below syntax. With this direct import approach, names get loaded into the calling module’s local symbol table and they don’t have to be called with
from math import pow, pi radius = 5 area = pi * pow(radius, 2) # 78.53981633974483
How to import all names of a module?
All names defined in a module could be imported directly using
from <module> import * statement. With this import, all names except the ones defined with an underscore “_” are imported. This is not a recommended approach. Because if two modules happen to have functions with the same name, it is harder to understand which module’s function is actually used by the calling module.
What happens if there are duplicate names?
If there are duplicate names in imported modules, a duplicate name defined later will replace the former. Numpy module’s
sin function will be used by the below module:
from math import sin from numpy import sin
How to provide alias names during import?
Imported modules or direct import names could be renamed for code readability.
import numpy as np from math import pow as power print(np.sin(10)) print(power(10, 2))
How does a Python interpreter find modules?
If a module named
hello is imported using
import hello statement, the Python interpreter searches for this module in the following locations and in the order given:
- The directory of the top-level file, i.e. the file being executed.
- The directories of PYTHONPATH, if this global environment variable is set.
- Standard Python installation path
Care must be taken to not to name the custom module same as standard modules. As local modules are given higher precedence, applications could end up replacing standard module’s behavior with local module.
How to run module as a script?
Same Python file could be used as a script or module depending on the presence of system variable
__name__ == "__main__" condition. so if the below segment is added to the
hello module could be run as a script.
if __name__ == "__main__": import sys say_hello(int(sys.argv)) #Runs say_hello when invoked $ python hello.py 5
How to get module information?
List of built-in modules could be printed using:
import sys print(sys.builtin_module_names)
Module’s content could be printed using
import math dir(math) ['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc'] # prints all built-ins import builtins dir(builtins) # prints all names in local scope dir()