views:

34080

answers:

7

How do I import a python module given its relative path?

For example, if dirFoo contains Foo.py and dirBar, and dirBar contains Bar.py, how do I import Bar.py into Foo.py?

Here's a visual representation:

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Foo wishes to include Bar, but restructuring the folder heirarchy is not an option.

+16  A: 

Be sure that dirBar has the __init__.py file -- this makes a directory into a Python package.

S.Lott
Note that this file can be completely empty.
Harley
If dirBar's parent directory is not in `sys.path` then the presence of `__init__.py` in the `dirBar` directory doesn't help much.
J.F. Sebastian
The above comment assumes that dirBar is a sub-package.
J.F. Sebastian
+11  A: 

(This is from memory so someone edit if I make a typo, please.)

If you structure your project this way:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

Then from Foo.py you should be able to do:

import dirFoo.Foo

Or:

from dirFoo.Foo import FooObject

EDIT 1:

Per Tom's comment, this does require that the src folder is accessible either via site_packages or your search path. Also, as he mentions, __init__.py is implicitly imported when you first import a module in that package/directory. Typically __init__.py is simply an empty file.

bouvard
Also mention that __init__.py is imported when the first module inside that package is imported. Also, your example will only work if src is in the site_packages (or in the search path)
Tom Leys
+16  A: 

You could also add the sub directory to your python path so that it imports as a normal script.

import sys
sys.path.append( <path to dirFoo> )
import Bar
Andrew Cox
+7  A: 

This is the relevant PEP:

http://www.python.org/dev/peps/pep-0328/

In particular, presuming dirFoo is a directory up from dirBar...

In dirFoo\Foo.py:

from ..dirBar import Bar
Peter Crabtree
Relative import doesn't work in non-package.
J.F. Sebastian
+7  A: 

The easiest method is to use sys.path.append().

However, you may be also interested in the imp module. It provides access to internal import functions.

# mod_name is the filename without the .py/.pyc extention
py_mod = imp.load_source(mod_name,filename_path) # Loads .py file
py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file

This can be used to load modules dynamically when you don't know a module's name.

I've used this in the past to create a plugin type interface to an application, where the user would write a script with application specific functions, and just drop thier script in a specific directory.

Also, these functions may be useful:

imp.find_module(name[, path])
imp.load_module(name, file, pathname, description)
monkut
+1  A: 

Add an _init_.py file:

dirFoo\
    Foo.py
    dirBar\
        __init__.py
        Bar.py

Then add this code to the start of Foo.py:

import sys
sys.path.append('dirBar')
import Bar
Josh
If `dirBar` is already a Python package (by the existence of `dirBar/__init__.py`), there is no need to append `dirBar` to `sys.path`, no? The statement `import Bar` from `Foo.py` should suffice.
Santa
A: 

In my opinion the best choice is to put __ init __.py in the folder and call the file with

from dirBar.Bar import *

It is not recommended to use sys.path.append() because something might gone wrong if you use the same file name as the existing python package. I haven't test that but that will be ambiguous.

jhana