importing a sibling module

Alex Martelli aleax at aleax.it
Fri Jan 4 05:14:58 EST 2002


"Clark C . Evans" <cce at clarkevans.com> wrote in message
news:mailman.1010117585.30880.python-list at python.org...
> Hello.  I have a directory structure that looks
> something like...
>
>     folder    files
> /zz/V13/lib  tool.py
> /zz/V13/app  prog.py
> /zz/V14/lib  tool.py
> /zz/V14/app  prog.py
    ...
> What I'd like to do, within prog.py is "import ../lib/tool.py"

Is the appropriate .../app directory the current working directory
when prog.py is running?  That doesn't sound likely to me.  So,
I don't think you really want this.  Still, if it really IS, the
following should (roughly speaking -- see later) 'work':

import imp
imp.load_module('tool', *imp.find_module('tool',['../lib']))


I suspect you rather want to find out in what directory the
currently running program resides, and then load the tool
module relative to THERE, rather than relative to the current
working directory as '../lib' does.  In this case, something
like the following could serve you better:

import os, sys, imp
app_dir, appfilename = os.path.split(sys.argv[0])
lib_dir = os.path.join(app_dir,'../lib')
imp.load_module('tool', *imp.find_module('tool',[libdir]))

Note that you may have several items in the list that you
pass as the second argument to find_module; so for example
you could have find_module search several directories to
find each given module you're looking for (you could have
one directory for version-specific modules, searched before
another directory for modules common to several versions,
etc, etc).


This is not optimal use of module imp, because it's "leaking"
(potentially) open-files.  For production use, you need to
put together a more articulated usage, such as:

try:
    file, path, description = imp.find_module('tool',[libdir])
except ImportError:
    # deal however you wish with the module not being found
else:
    try: tool = imp.load_module(file,path,description)
    finally: file.close()


Note that the module object is returned by load_module (if the
import is successful) and you may use it directly.  load_module
also installs the module it's importing (*or _reloading_*) in
sys.modules['tool'], so you may follow up with an
    import tool
to inject the name 'tool' into your namespace (as an alternative
to just binding name 'tool' to the result of load_module, which
is normally preferable anyway).

Further note the "or reloading": load_module does NOT look in
sys.modules first, so, even if the module was already loaded,
it's going to be imported again, as with a reload() call it
would be.  You can of course first check sys.modules yourself
if that's not what you want.


Alex






More information about the Python-list mailing list