Lets say there is a system wide module named foobar, and a django app named foobar too, and I cannot edit none of them, because they are external projects.

Now, I would like to use the system foobar module, not the application, but it does not work:

$ python --version
Python 2.7.3

$ ./manage.py --version
1.3.1

$ ./manage.py shell
>>> import foobar
>>> print (foobar)
<module 'foobar' from '/path/to/myproject/foobar/__init__.pyc'>

How can I do ? I suppose I would have <module 'foobar' from '/usr/lib/python2.7/dist-packages/foobar/__init__.pyc'> instead.

#

Python looks for packages at the locations defined in the environment variable PYTHONPATH. You can modify this from within Python quite easily:

https://docs.python.org/2/install/index.html#modifying-python-s-search-path

You'll want to change sys.path so that the directory containing the system foobar module is before the application directory.

Assuming your sys.path looks like:

>>> import sys
>>> sys.path
['', '/usr/local/lib/python2.7/site-packages']

and foobar is in both the current working directory (indicated with ''), and the system site-packages directory, you want to get the system foobar closer to the front of the list:

>>> sys.path.insert(0, '/usr/local/lib/python2.7/site-packages/foobar')
>>> sys.path
['/usr/local/lib/python2.7/site-packages/foobar', 
 '', '/usr/local/lib/python2.7/site-packages']

Note that this change to the path will only apply for the running process/instance of Python (in this case, the interactive session), and later processes will start up with the original path.

Solution without modifying the path

If you can't or don't want to modify sys.path, you can use the imp module to manually import a module:

import imp

name = 'foobar'
path = '/usr/local/lib/python2.7/site-packages/foobar'

fp, pathname, description = imp.find_module(name, path)
try:
    imp.load_module(name, fp, pathname, description)
finally:
    # Make sure the file pointer was closed:
    if fp:
        fp.close()

Solution with modifying the path only temporarily

This solution doesn't need to know where the system foobar package is ahead of time, only that you want the one that isn't in the current directory:

import imp
import sys

# Temporarily remove the current working directory from the path:
cwd = sys.path.pop(0)

# Now we can import the system `foobar`:
import foobar

# Put the current working directory back where it belongs:
sys.path.insert(0, cwd)

 

Try this, no hard code path

import os
import sys
PROJECT_DIR = os.path.dirname(__file__) 
# make sure the path is right, it depends on where you put the file is

# If PROJECT_DIR in sys.path, remove it and append to the end.
syspath = sys.path
syspath_set = set(syspath)
syspath_set.discard(PROJECT_DIR)
sys.path = list(syspath_set)

sys.path.append(PROJECT_DIR)

# Then try
import foobar

# At last, change it back, prevent other import mistakes
sys.path = syspath