Skip to main content

All About Importing Modules and from Packages

Module?

A module is just a Python file with the corresponding .py extension. So if you're talking about the math module then there is a corresponding math.py file that contains functions, classes, and constants that are meant to be used by other Python files.

Where does Python look for modules

If you have written a python module under say a_module.py in a directory of code.

And you have a script called a_script.py in directory called scripts. You would like to use the a_module in a_script.py by importing it.

import a_module

Then you try to run the a_script.py by running python3 scripts/a_script.py it will fail with

$ python3 scripts/a_script.py
Traceback (most recent call last):
  File "scripts/a_script.py", line 1, in <module>
    import a_module
ModuleNotFoundError: No module named 'a_module'

When Python imports a module it will try to find a package or module. But where does it look? Python has a simple algorithm for finding a module with a given name. It will look for a file called a_module.py in the directories listed in the variable sys.path.

>>> import sys
>>> type(sys.path)
<class 'list'>
>>> for path in sys.path:
...     print(path)
... 
/Users/brettmz-admin/dev_trees/psych-214-fall-2016/sphinxext
/usr/local/Cellar/python/3.7.2_1/Frameworks/Python.framework/Versions/3.7/lib/python37.zip
/usr/local/Cellar/python/3.7.2_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7
/usr/local/Cellar/python/3.7.2_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload
/Users/brettmz-admin/Library/Python/3.7/lib/python/site-packages
/Users/brettmz-admin/dev_trees/grin
/Users/brettmz-admin/dev_trees/rmdex
/usr/local/lib/python3.7/site-packages

It doesn't search recursively, it will only search in the directory that is listed under sys.path. And as you can see the code directory is not in sys.path which is why Python could not import a_module.py.

To fix this you can just simply append to the sys.path list like so:

import sys
sys.path.append('code')

import a_module

Now this will work as expected. This simple search algorithm for module also works for packages, it searches for packages then the module the same way.

Information from: https://bic-berkeley.github.io/psych-214-fall-2016/sys_path.html 

https://stackoverflow.com/questions/21819649/namespace-vs-regular-package What are named space packages. It is still searched in the sys.path list