You thought you understood how to import things, but then you ran into a problem where nothing seemed to work like you thought it did. What happened? Let’s find out!
If you’re in a hurry, skip to the bottom for a tl;dr.
Consider the following example project:
This project consists of a single package (
demonstrator) which contains
several modules (
demo_zany) and a
plugins) which contains a single module (
color). Remember that
__init__.py files are what define these directories as packages in the
demonstrator package is primarily intended to be imported and used as a
library. But it also contains a few scripts that are designed to be directly
Let’s look at the contents of
And the contents of
And the contents of
demo.py uses absolute imports,
demo_relative.py uses relative imports, and
demo_zany.py uses absolute imports but assumes that its sibling
modules/packages are at the top level.
Which import styles do you think will work? Make your guesses now!
The Right Way
Did you guess correctly? Good. So did I!
The Wrong Way
It turns out that many people try to execute the scripts like this:
Well, look at that; the results are exactly the opposite of what we saw when we
demo.py doesn’t work when executed this way because the directory that
demonstrator is not listed in
sys.path. This could be fixed using
some manual tweaking of
sys.path, but it’s easier to just execute using the
-m option, which solves the problem.
demo_relative.py doesn’t work when executed this way because files executed by
filename aren’t considered part of any package. This can’t be fixed except by
demo_zany.py works when executed this way because the directory containing
demo_zany.py gets added to
sys.path, which means
both accessible as top-level modules/packages. This is undesirable because
one of our modules might accidentally shadow one of the standard library
modules/packages if we weren’t careful with our modules’ names.
Always execute your scripts using the
python -m package.module form. This
will ensure that both absolute and relative imports work as expected.