Import external libraries and organize your code into functional chunks. For interactive reading and executing code blocks and find b05-pypckg.ipynb, or install Python and JupyterLab locally.
Watch this section as a video
Watch this section as a video on the @Hydro-Morphodynamics channel on YouTube.
Import Packages or Modules¶
Importing a package or module in Python makes external functions and other elements (such as objects) of modules accessible in a script. The functions and other elements are stored within another Python file (.py) in some /site_packages/ folder (directory) of the interpreter environments. Thus, to use a non-standard package, it needs to be downloaded and installed first. Standard Python packages (e.g., os, math) are always accessible and other can be added with conda or pip (read more pip-installing).
The os package provides basic system-terminal-like commands, for example, to manage folder directories. So let’s import this essential package:
import os
print(os.getcwd()) # print current working directory
print(os.path.abspath('')) # print directory of script runningOverview of Import Options¶
Here is an overview of options to import packages or modules (hierarchical parts of packages):
| Command | Description | Usage of attributes |
|---|---|---|
import package-name | Import an original module | package.item() |
import package-name as nick-name | Import module and rename (alias) it in the script | nick-name.item() |
from package-name import item | Import only a function, class or other items | item() |
from package-name import * | Import all items | item() |
Example¶
import matplotlib.pyplot as plt # import pyplot from the matplotlib module and alias it with plt
import math as m
x = []
y = []
for e in range(1, 10):
x.append(e)
y.append(e**2)
plt.plot(x, y)What is the best way to import a package or module?¶
There is no global answer to this question. However, be aware that from package-name import * overwrites any existing variable or other items in the script. Thus, only use * when you are aware of all contents of a module or package.
pi = 9.112 # define a float called pi
print("Pi is not %1.3f." % pi)
from math import pi # this overwrites the before defined variable pi
print("Pi is %1.3f." % pi)What items (attributes, classes, functions) are in a module?¶
Sometimes we want to explore modules or check variable attributes. This is achieved with the dir() command:
import sys
print(sys.path)
print(dir(sys.path))
a_string = "zabaglione"
print(", ".join(dir(a_string)))Create a new Module¶
In object-oriented programming and code factorization, writing custom, new modules is an essential task. To write a new module, first, create a new script. Then, open the new script and add some parameters and functions.
# icecreamdialogue.py
flavors = ["vanilla", "chocolate", "bread"]
price_scoops = {1: "two euros", 2: "three euros", 3: "your health"}
welcome_msg = "Hi, I only have " + flavors[0] + ". How many scoops do you want?"icecreamdialogue.py can now either be executed as a script (nothing will happen visibly) or imported as a module to access its variables (e.g., icecreamdialogue.flavors):
import icecreamdialogue as icd
print(icd.welcome_msg)
scoops_wanted = 2
print("That makes {0} please".format(icd.price_scoops[scoops_wanted]))Make Script Stand-alone¶
As an alternative, we can append the call to items in icecreamdialogue.py in the script and run it as a stand-alone script by adding an if __name__ == "__main__": block:
# icecreamdialogue_standalone.py
flavors = ["vanilla", "chocolate", "bread"]
price_scoops = {1: "two euros", 2: "three euros", 3: "your health"}
welcome_msg = "Hi, I only have " + flavors[0] + ". How many scoops do you want?"
if __name__ == "__main__":
print(welcome_msg)
scoops_wanted = 2
print("That makes {0} please".format(price_scoops[scoops_wanted]))Now we can run icecreamdialogue_standalone.py in a terminal (e.g., Linux Terminal, PyCharm’s Terminal tab at the bottom of the window, or in Atom using platformio-ide-terminal).
C:\temp\ python icecreamdialogue_standalone.pyStandalone Scripts with Input Parameters¶
To make the script more flexible, we can define, for instance, scoops_wanted as an input variable of a function.
# icecreamdialogue_standalone_withinput.py
flavors = ["vanilla", "chocolate", "bread"]
price_scoops = {1: "two euros", 2: "three euros", 3: "your health"}
welcome_msg = "Hi, I only have " + flavors[0] + ". How many scoops do you want?"
def dialogue(scoops_wanted): #formerly in the __main__ statement
print(welcome_msg)
print("That makes {0} please".format(price_scoops[scoops_wanted]))
if __name__ == "__main__":
# import the terminal function emulator sys
import sys
if len(sys.argv) > 1: # make sure input is provided
# if true: call the dialogue function with the input argument
dialogue(int(sys.argv[1]))Now, we can run icecreamdialogue_standalone_withinput.py in a terminal.
C:\temp\ python3 icecreamdialogue_standalone.py 2Initialization of a Package (Hierarchically Organized Module)¶
Good practice involves that one script does not exceed 50-100 lines of code (except inline docs and multiline variables). In consequence, a package will most likely consist of multiple scripts that are stored in one folder and one core script serves for the initiation of the scripts. This core script is called __init__.py and Python will always invoke this script name in a package folder. Example structure of a module called icecreamery:
icecreamery(folder name)__init__.py- package initiation Python scripticecreamdialogue.py- dialogue producing Python scripticecream_maker.py- virtual ice cream producing Python script
To automatically invoke the two relevant scripts (sub-modules) of the icecreamery module, the __init__.py needs to include the following:
# __init__.py
print(f'Invoking __init__.py for {__name__}') # not absolutely needed ..
import icecreamery.icecreamdialogue, icecreamery.icecream_maker# example usage of the icecreamery package
import icecreamery
print(icecreamery.icecreamdialogue.welcome_msg)Do you remember the dir() function? It is intended to list all modules in a package, but it does not do so unless we defined an __all__ list in the __init__.py.
# __init__.py with __all__ list
__all__ = ['icecreamdialogue', 'icecream_maker']ThThe full example of the icecreamery_all package is also available in an icecream repository.
# example usage of the icecreamery package
from icecreamery_all import *
print(icecreamdialogue.welcome_msg)Package Creation Summary¶
A hierarchically organized package contains an __init__.py file with an __all__ list to invoke relevant module scripts. The structure of a module can be more complex than the above example list (e.g., with sub-folders). When you write a package, consider using meaningful script and variable names, along with appropriate documentation.
Reload (Re-import) a Package or Module¶
Since Python3, reloading a module requires importing the importlib module first. Reloading makes only sense if you are actively writing a new module. To reload any module type:
import importlib
importlib.reload(my-module)