Relative imports in python 2.5
Take a look at the following info from PEP 328:
Relative imports use a module's
__name__
attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to'__main__'
) then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.
When you run foo.py
as a script, that module's __name__
is '__main__'
, so you cannot do relative imports. This would be true even if mypackage
was on sys.path
. Basically, you can only do relative imports from a module if that module was imported.
Here are a couple of options for working around this:
1) In foo.py
, check if __name__ == '__main__'
and conditionally add mypackage
to sys.path
:
if __name__ == '__main__':
import os, sys
# get an absolute path to the directory that contains mypackage
foo_dir = os.path.dirname(os.path.join(os.getcwd(), __file__))
sys.path.append(os.path.normpath(os.path.join(foo_dir, '..', '..')))
from mypackage import bar
else:
from .. import bar
2) Always import bar
using from mypackage import bar
, and execute foo.py
in such a way that mypackage
is visible automatically:
$ cd <path containing mypackage>
$ python -m mypackage.foo.foo
My solution looks a bit cleaner and can go at the top, with all the other imports:
try:
from foo import FooClass
except ModuleNotFoundError:
from .foo import FooClass