Hi,
I was looking for a nice idiom for interpackage imports as I found
this thread.
Here come a couple of solutions I came up with. Any discussion is
welcome.
I assume the same file structure
\ App
| main.py
+--\subpack1
| | __init__.py
| | module1.py
|
+--\subpack2
| | __init__.py
| | module2.py
When you run main.py all imports relative to \App work fine, so the
only problem is running a module from within a subpackage as a script.
I therefore assume we want to run module1.py as a script, which wants
to import module2.
I hope the following solutions are self-evident
================= solution 1
--> in module1.py
import sys, os
if __name__ == '__main__':
sys.path.append(os.path.normpath(__file__+'/../..'))
import subpack2.module2
================= solution 2
--> in subpack1/__init__.py
import sys, os
_top_package_level = 1 # with current package being level 0
_top_package = os.path.normpath(__file__ + '/..'*(_top_package_level
+1))
if _top_package not in sys.path:
sys.path.append(_top_package)
--> in module1 or any module in the package, which requires import
relative to the package top
import __init__
import subpack2.module2
================= solution 3
--> in package_import.py, somewhere on the PYTHONPATH ( perhaps in
standard lib
def set_top_package(module, level):
_top_package = os.path.normpath(module + '/..'*(level+1))
if _top_package not in sys.path:
sys.path.append(_top_package)
class absolute_import(object):
def __init__(self, module, level):
self.level = level
self.module = module
def __enter__(self):
sys.path.insert( 0,
os.path.normpath(self.module + '/..'*(self.level+1))
)
def __exit__(self, exc_type, exc_val, exc_tb):
del sys.path[0]
--> in module1
import package_import
package_import.set_top_package(__file__, 1)
import subpack2.module2
--> or in module1
import package_import
with package_import.absolute_import(__file__, 1):
import subpack2.module2
...