views:

218

answers:

7

Is it possible to import modules based on location?

(eg. do all modules i import have to be in /usr/lib64/python2.5/ or a similar dir?)

I'd like to import a module that's local to the current script.

+3  A: 

You can edit your PYTHONPATH to add or remove locations that python will search whenever you attempt an import.

apphacker
+3  A: 
  • python will import from the current directory by default.

  • sys.path is the variable that controls where python searches for imports.

Mark Harrison
+7  A: 

You can extend the path at runtime like this:

sys.path.extend(map(os.path.abspath, ['other1/', 'other2/', 'yourlib/']))
justinhj
A: 

You can import module that are in the same path the module you are importing to. For example:

Directory contains: mod1.py, mod2.py

mod2.py
--------
import mod1

Or you can add any directory to your PYTHON_PATH variable:

import sys
sys.path.extend('/user/some/other/directory')
import mod1
jcoon
A: 

It searches in ./lib by default.

Beau Martínez
A: 

For low-level control over the import process, the imp module lets you import modules from arbitrary open files under arbitrary names.

For example, if this is foo.py:

def x():
    print 'hello, world'

Then this code:

import imp

with open('foo.py', 'r') as module_file:
    imp.load_module('module_name', module_file, '', ('', 'r', imp.PY_SOURCE))

import module_name

module_name.x()

prints "hello, world".

andrew
A: 

Use init.py

The only problem with doing dynamic modification of sys.path is that you need to repeat it in every script and hard-code the pathnames. That gets messy and non DRY if you have even two or three files.

Instead, if your file structure looks like this:

~/foo/__init__.py
~/foo/foo.py
~/foo/bar/__init__.py
~/foo/bar/baz.py

Here the init.py's are blank files created with touch, while foo.py and baz.py are actual python scripts. Then you can do something like this:

import sys
try:
    from foo import foo
    from foo.bar import baz
except ImportError:
    "%s is not in %s. Add to your PYTHONPATH in ~/.bashrc" % \
    (os.path.expanduser("~/foo"),sys.path)

Structuring your stuff as a package from the beginning is a little more work but makes it much easier to scale the project later and to see where imports are coming from. Moreover, if you move stuff around, you can use a single symlink rather than doing a find/replace through your codebase. E.g. if you moved '~/foo' to '~/downloads/foo', just do this:

cd ~
ln -s ~/downloads/foo foo

And all your imports will still work.

ramanujan