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
-
It searches in ./lib by default.
-
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".
-
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.
0 comments:
Post a Comment