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.
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.
You can edit your PYTHONPATH to add or remove locations that python will search whenever you attempt an import.
python will import from the current directory by default.
sys.path is the variable that controls where python searches for imports.
You can extend the path at runtime like this:
sys.path.extend(map(os.path.abspath, ['other1/', 'other2/', 'yourlib/']))
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
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".
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.