In this lesson, you’ll learn about subpackages. Packages can contain nested subpackages to arbitrary depth. For starters, let’s make one more modification to the example package directory as follows:

The four modules (mod1.py, mod2.py, mod3.py, and mod4.py) are defined as they were before. But now, instead of being lumped together into the pkg directory, they are split out into two subpackage directories: sub_pkg1 and sub_pkg2.
Importing still works the same as you saw before. Syntax is similar, but additional dot notation is used to separate the package name from the subpackage name:
>>> import pkg.sub_pkg1.mod1
>>> pkg.sub_pkg1.mod1.load_data()
loading data using mod1.load_data()
>>> from pkg.sub_pkg1 import mod2
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'help', 'mod2', 'pkg']
>>> mod2.clean_data()
cleaning data using mod2.clean_data()
>>> from pkg.sub_pkg2.mod3 import merge_data
>>> merge_data()
merging data using mod3.merge_data()
>>> from pkg.sub_pkg2.mod4 import Winner as Result
>>> x = Result()
>>> x
<pkg.sub_pkg2.mod4.Winner object at 0x108159588>

danny vw on March 4, 2020
Short question: if we have an additional level, e.g., grandparent_pkg/pkg1/sub_pkg2/mod3.py and suppose I need to go via the grandparent to reach some other modules in grandparent_pkg/pkg2/sub_pkg7/mod8.py. To go up to the grandparent from within mod3.py do we use then something like ../..pkg2.sub_pkg7/mod8.py ?