How to properly use relative or absolute imports in Python modules?

sorin picture sorin · Sep 1, 2010 · Viewed 23k times · Source

Usage of relative imports in Python has one drawback, you will not be able to run the modules as standalones anymore because you will get an exception: ValueError: Attempted relative import in non-package

# /test.py: just a sample file importing foo module
import foo
...

# /foo/foo.py:
from . import bar
...
if __name__ == "__main__":
   pass

# /foo/bar.py: a submodule of foo, used by foo.py
from . import foo
...
if __name__ == "__main__":
   pass

How should I modify the sample code in order to be able to execute all: test.py, foo.py and bar.py

I'm looking for a solution that works with python 2.6+ (including 3.x).

Answer

Jacek Konieczny picture Jacek Konieczny · Sep 1, 2010

You could just start 'to run the modules as standalones' in a bit a different way:

Instead of:

python foo/bar.py

Use:

python -mfoo.bar

Of course, the foo/__init__.py file must be present.

Please also note, that you have a circular dependency between foo.py and bar.py – this won't work. I guess it is just a mistake in your example.

Update: it seems it also works perfectly well to use this as the first line of the foo/bar.py:

#!/usr/bin/python -mfoo.bar

Then you can execute the script directly in POSIX systems.