In this lesson, you’ll learn about importing *
from a package. For the purposes of the following discussion, the previously defined package is expanded to contain some additional modules:

There are now four modules defined in the pkg
directory. Their contents are as shown below.
mod1.py
:
def load_data():
print('loading data using mod1.load_data()')
class Customer:
pass
mod2.py
:
def clean_data():
print('cleaning data using mod2.clean_data()')
class Location:
pass
mod3.py
:
def merge_data():
print('merging data using mod3.merge_data()')
class Message:
pass
mod4.py
:
def send_mail():
print('sending mail using mod4.send_mail()')
class Winner:
pass
You have already seen that when import *
is used for a module, then all objects from the module are imported into the local symbol table, except those whose names begin with an underscore, as usual:
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'help']
>>> from pkg.mod3 import *
>>> dir()
['Message', '__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'merge_data']
>>> merge_data()
merging data using mod3.merge_data()
>>> Message
<class 'pkg.mod3.Message'>
The analogous statement for a package is this:
from <package_name> import *
Here’s what it does:
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'help']
>>> from pkg import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'help']
Hmph. Not much. You might have expected (assuming you had any expectations at all) that Python would dive down into the package directory, find all the modules it could, and then import them all. But as you can see, by default that is not what happens.
Instead, Python follows this convention: if the __init__.py
file in the package directory contains a list named __all__
, then it is taken to be a list of modules that should be imported when the statement from <package_name> import *
is encountered.
For the present example, suppose you create an __init__.py
in the pkg
directory like this:
__all__ = [
'mod1',
'mod2',
'mod3',
'mod4'
]
Now from pkg import *
imports all four modules:
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'help']
>>> from pkg import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'help', 'mod1', 'mod2', 'mod3', 'mod4']
>>> mod1.load_data()
loading data using mod1.load_data()
>>> mod4.Winner
<class 'pkg.mod4.Winner'>
Using import *
still isn’t considered terrific form, any more for packages than it is for modules. But this facility at least gives the creator of the package some control over what happens when import *
is specified. (In fact, it provides the capability to disallow it entirely, simply by declining to define __all__
at all. As you have seen, the default behavior for packages is to import nothing.)
By the way, __all__
can be defined in a module as well and serves the same purpose, which is to control what is imported with import *
. For example, modify mod1.py
as follows:
__all__ = ['load_data']
def load_data():
print('loading data using mod1.load_data()')
class Customer:
pass
Now, an import *
statement from pkg.mod1
will only import what is contained in __all__
:
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'help']
>>> from pkg.mod1 import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'help', 'load_data']
>>> load_data()
loading data using mod1.load_data()
>>> Customer
Traceback (most recent call last):
File "<input>", line 1, in <module>
Customer
NameError: name 'Customer' is not defined
load_data()
is now defined in the local namespace, but Customer
is not, because the latter is not in __all__
. In summary, __all__
is used by both packages and modules to control what is imported when import *
is specified. But the default behavior is different:
- For a package, when
__all__
is not defined, thenimport *
does not import anything. - For a module, when
__all__
is not defined, thenimport *
imports everything (except—you guessed it—names starting with an underscore).
Jakob Fredriksson on July 28, 2020
I’ve been grinding Python for a couple of months by now but I’ve been cheating and “skipped” some basics. Basics like this. Great teaching throughout this course, much desired and much needed basics fell in place.
Your color-theme btw? It’s awesome!