When writing an application in python, it can be very convenient to be able to import a module from the top of your module tree. Eg.
import myapp.config instead of (python 2.5 only) relative imports:
import ....config. To do this one would have to make
myapp a package. The normal way to do this is to put your application directory (which now has to be named
myapp) somewhere in python’s package search path. This isn’t all to convenient.
The solution: manually set up your package module:
def setup_virtual_package(name, path=os.curdir):
""" Sets up a package at the given path with a given
modulePath = os.path.abspath(path)
f, fn, suffix = imp.find_module('__init__',
imp.load_module(name, f, fn, suffix)
sys.modules[name].__path__ = [modulePath]
import myapp.something works like a charm.
When you’ve got a big python application, you’ll usually split it up in modules. One big annoyance I’ve had is that a module inside a directory cannot (easily) import a module higher up in the tree. Eg: drawers/gtk.py cannot import state/bla.py.
This is usually solved by making the application a package. This allows for
import myapp.drawers.gtk from everywhere inside your application. To make it a package though, you need to add the parent directory in the
sys.path list. But unfortunately this also includes all other subdirectories of the parent directory as packages.
However, when the package module (eg:
myapp) was already loaded, then the path from which
myapp was loaded is used to find the submodules (eg:
sys.path isn’t looked at, at all. So, here is the trick:
p = os.path.dirname(__file__)
Note that this script doesn’t work when directly executed, because the
__file__ attribute is only available when loaded as a module.
Save this script as
loader.py in the root of your application.
import loader from the main script in your app, and you’ll be able to import modules by
myapp is the root directory name of your application.