Assume there is a package name called 'abc'. We need to import package 'abc' to use it.
import abc
In this case, 'abc' would be a simple python file or a directory that contains python files.
Then how does python find the modules and packages?
['',
'/Users/song-eun-u/anaconda3/bin',
'/Users/song-eun-u/anaconda3/lib/python36.zip',
'/Users/song-eun-u/anaconda3/lib/python3.6',
'/Users/song-eun-u/anaconda3/lib/python3.6/lib-dynload',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/aeosa',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/IPython/extensions',
'/Users/song-eun-u/.ipython']
When finding modules and packages, python checks sys.modules first, if none, checks built in modules, and for the last checks directory path assigned in sys.path. If there's none in overall, it raises an error 'ModuleNotFoundError'.
To import a local package
Directory path is same all the time regardless of imported file and its path.
└── my_app
├── main.py
├── package1
│ ├── module1.py
│ └── module2.py
└── package2
├── __init__.py
├── module3.py
├── module4.py
└── subpackage1
└── module5.py
It is a project named 'my app' and has two packages 1 and 2.
Importing package1 and package2 using Absolute path is following.
from package1 import module1
from package1.module2 import function1
from package2 import class1
from package2.subpackage1.module5 import function2
Starting point of the path is the highest point of 'my app' project.
Ex) Importing function2 in module5 in subpackage1 in linux directory path format.
my_app/package2/subpackage1/module5.py
Current directory will be included in sys.path as default. Therefore, absolute path starts from current directory.
One weakness could be its length. Alternative way is relative path.
It defines the path starting from the imported package location, so it is usually used when local package is imported in another local package.
#package2/module3.py
from . import class1
from .subpackage1.module5 import function2
One weakness is that it may create confusion and path location needs to be changed if file location is changed.
I'm wrapping up this post with my example calculator for relative and absolute path.
└── calculator
├── main.py
├── package1
├── __init__.py
│ ├── module1.py
│ └── module2.py
Absolute path
from package1.module1 import add
from package1.module2 import sub
Relative path
#package1.module1
from .module2 import sub