In this lesson, you’ll learn about Python packages. Suppose you have developed a very large application that includes many modules. As the number of modules grows, it becomes difficult to keep track of them all if they’re dumped in one location. This is particularly true if they have similar names or functionality. You might want a way to group and organize them.
Packages allow for a hierarchical structuring of the module namespace using dot notation. In the same way that modules help avoid collisions between global variable names, packages help avoid collisions between module names.
Creating a package is quite straightforward, since it makes use of the operating system’s inherent hierarchical file structure. Consider the following arrangement:

Here, there is a directory named pkg
that contains two modules, mod1.py
and mod2.py
. Take a look at the contents of the modules. Here’s mod1.py
:
def load_data():
print('loading data using mod1.load_data()')
class Customer:
pass
Here’s mod2.py
:
def clean_data():
print('cleaning data using mod2.clean_data()')
class Location:
pass
Given this structure, if the pkg
directory resides in a location where it can be found (in one of the directories contained in sys.path
), you can refer to the two modules with dot notation (pkg.mod1
, pkg.mod2
) and import them with the syntax you’re already familiar with:
import <module_name>[, <module_name> ...]
Here’s what that looks like in practice:
>>> import pkg.mod1, pkg.mod2
>>> pkg.mod1.load_data()
loading data using mod1.load_data()
>>> x = pkg.mod2.Location()
>>> x
<pkg.mod2.Location object at 0x10818c550>
You can also use this syntax:
from <module_name> import <name(s)>
Here’s what that looks like in practice:
>>> from pkg.mod1 import load_data
>>> load_data()
loading data using mod1.load_data()
You can also use this syntax:
from <module_name> import <name> as <alt_name>
Here’s what that looks like in practice:
>>> from pkg.mod2 import Location as Primary
>>> y = Primary()
>>> y
<pkg.mod2.Location object at 0x10d8ed2b0>
You can import modules with these statements as well:
from <package_name> import <modules_name>[, <module_name> ...]
from <package_name> import <module_name> as <alt_name>
Here’s what that looks like in practice:
>>> from pkg import mod1
>>> mod1.load_data
<function load_data at 0x101b37f28>
>>> from pkg import mod2 as foo
>>> foo.clean_data()
cleaning data using mod2.clean_data()
You can technically import the package as well:
>>> import pkg
>>> pkg
<module 'pkg' (namespace)>
But doing that is of little use. Though this is, strictly speaking, a syntactically correct Python statement, it doesn’t do much of anything useful. In particular, it doesn’t place any of the modules in pkg
into the local namespace:
>>> pkg.mod1
Traceback (most recent call last):
File "<input>", line 1, in <module>
pkg.mod1
AttributeError: module 'pkg' has no attribute 'mod1'
>>> pkg.mod2.Location
Traceback (most recent call last):
File "<input>", line 1, in <module>
pkg.mod2.Location
AttributeError: module 'pkg' has no attribute 'mod2'
>>> pkg.mod1.load_data()
Traceback (most recent call last):
File "<input>", line 1, in <module>
pkg.mod1.load_data()
AttributeError: module 'pkg' has no attribute 'mod1'
To actually import the modules or their contents, you need to use one of the forms you saw above.
macblanelw on July 4, 2020
This does not work for me: bpython version 0.18 on top of Python 3.8.2 /usr/bin/python3
Clearly, my version of python does not assume that a directory is a module, or will not treat the directory as one. Anything I can do? My current path is ~/projects/python/ModulesAndPackages/pkg/ I tried this from within /pkg/ and above it. Same results.