Джанго абсолютный импорт

Допустим, существует системный модуль с именем foobarи приложение Django с именем foobar и я не могу редактировать ни один из них, потому что это внешние проекты.

Теперь я хотел бы использовать системный модуль foobar, а не приложение, но он не работает:

$ 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'>

Как я могу сделать? Я полагаю <module 'foobar' from '/usr/lib/python2.7/dist-packages/foobar/__init__.pyc'> вместо.

2 ответа

Решение

Python ищет пакеты в местах, определенных в переменной среды PYTHONPATH, Вы можете изменить это изнутри Python довольно легко:

https://docs.python.org/2/install/index.html

Вы хотите изменить sys.path так что каталог, содержащий системный модуль foobar, находится перед каталогом приложения.

Предполагая ваш sys.path похоже:

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

а также foobar находится в текущем рабочем каталоге '') и система site-packages каталог, вы хотите получить систему foobar ближе к началу списка:

>>> 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']

Обратите внимание, что это изменение пути будет применяться только к запущенному процессу / экземпляру Python (в данном случае, к интерактивному сеансу), и последующие процессы будут запускаться с исходным путем.

Решение без изменения пути

Если вы не можете или не хотите изменять sys.path, вы можете использовать imp Модуль для ручного импорта модуля:

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()

Решение с изменением пути только временно

Это решение не должно знать, где система foobar Пакет опережает время, только вам нужен тот, которого нет в текущем каталоге:

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)

Попробуйте это, без жесткого пути кода

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
Другие вопросы по тегам