Modules
Modules are fundamental to the programming model of Python. Modules are programming units that (should) consist of related variables and functions that form a coherent block of data+procedures (functions). They are an extension of the concept of packaging code that we have already studied with functions.
In Python every file you write is a module. The name of the module is the file name without the extension. Every Python file must end in .py
regardless of your operating system, so if you write a file mycode.py
the corresponding module is mycode
. If you are using Jupyter you will need to export your code into a script in order to create a new module (Notebook tab -> Export to -> Executable Script).
Modules that are not run as the main program must be imported for its contents to be accessible. When a module is imported, it is compiled to a special representation called bytecode. A new file of the same base name with the suffix .pyc
will be created.
Many modules and packages (collections of modules) are available through a base Python installation. Conda-forge provides thousands more. We have already seen a handful of these built-in modules.
import math
import matplotlib.pyplot
When we import a module we bring in its namespace. A namespace is an environment that holds a group of identifiers, such as variable and function names. In Python the namespaces take the name of the module in which they are defined. Namespaces can be renamed when the module is imported, but not afterward.
Importing Modules
With a simple import statement we must refer to the module’s components with its native namespace.
import math
import os
import numpy
z=math.sqrt(x)
home_dir=os.getenv("HOME")
A=numpy.zeros(200)
We can select only certain components with from
from modulename import func1, func2
Now only func1 and func2 can be used, and we do _not* precede their names with the native namespace.
z=func1(x,y)
w=a+b*func2(z)
To import all symbols without a prefix use
from modulename import *
This statement imports all names that do not begin with a single underscore (_) and makes them accessible without being preceded by the module name.
We can also rename individual symbols
from math import sqrt as squareroot
w=squareroot(10.)
One of the most commonly used versions of import changes the name of the namespace, typically to something simpler.
import numpy as np
import pandas as pd
z=np.zeros(200)
data=pd.read_csv("my_data.txt")
Main Modules
When you run a script directly through the interpreter, such as by using the Run arrow in Spyder, it is in the “main” namespace. Your module can also be imported into the interpreter or into another module. It will still execute everything in the module, including requests for input and the like, unless you use the special variables __name__ and __main__ (two underscores on each side). If you use __main__ you can place all code you want to execute only when run directly after a conditional.
if __name__=="__main__":
do_work
It is customary to include code for the main namespace into a function named main()
.
def main():
do_work
if __name__=="__main__:"
main()
Example
#from __future__ import print_function, division #Python 2.7
from math import sqrt
def MySqrt(x):
"""Babylonian method."""
my_sqrt=x/2.
s0=x
tol=1.e-12
while abs(my_sqrt-s0)>tol:
s0=my_sqrt
my_sqrt=0.5*(my_sqrt+x/my_sqrt)
return my_sqrt
def relerr(x1,x2):
return abs((x2-x1)/x2)
def main():
print("{:s}{:s}{:s}".format("x".center(20),"sqrt".center(10),"rel_error".rjust(14)))
N=5
for i in range(-N,N+1):
x=10.0**(-i)
print("{:14.3e}{:14.3e}{:15.7e}".format(x,sqrt(x),relerr(MySqrt(x),sqrt(x))))
if __name__=="__main__":
main()
Exercise
Type in the example. Save it into a file called rooter.py
. Type in and save a file testmain.py
import rooter
sqrtrt=rooter.MySqrt(11.0)
print(sqrtrt)
First run rooter.py as a standalone script, then run testmain.py. What’s the difference?