Как я могу предотвратить импорт модуля Python? - PullRequest
13 голосов
/ 04 декабря 2009

Например, я хочу сделать плагин sql alchemy для другого проекта. И я хочу назвать этот модуль sqlalchemy.py. Проблема в том, что это мешает мне импортировать sqlalchemy:

#sqlalchemy.py
import sqlalchemy 

Это заставит модуль импортировать сам. Я пробовал это, но это не похоже на работу:

import sys
#Remove the current directory from the front of sys.path
if not sys.path[0]:
    sys.path.pop(0)
import sqlalchemy

Есть предложения?

Ответы [ 3 ]

12 голосов
/ 04 декабря 2009

Редактировать : поскольку ФП упомянул, что проблема заключается в относительном импорте, который предпочтительнее абсолютного, самое простое решение для конкретной проблемы ФП - добавить в начале модуля from __future__ import absolute_import который меняет это "предпочтение" / ordering .

Следующее по-прежнему относится к щекотливой проблеме двух конфликтующих абсолютных импортов (что, кажется, не то, с чем сейчас сталкивается ОП):

После того, как вы импортировали модуль с именем x, этот модуль записан в sys.modules['x'] - изменение sys.path, как вы делаете, не изменит sys.modules. Вам также необходимо изменить sys.modules напрямую.

Например, рассмотрим:

$ cat a/foo.py
print __file__; import sys; sys.path.insert(0, "b"); del sys.modules["foo"]; import foo
$ cat b/foo.py
print __file__
$ python2.5 -c'import sys; sys.path.insert(0, "a"); import foo'
a/foo.py
b/foo.py

(при повторном запуске файлы .pyc будут показаны вместо файлов .py, конечно).

Не самый чистый подход, и, конечно, таким образом, оригинальный модуль foo неизбежно больше не будет доступен извне (так как его запись в sys.modules была смещена), но вы можете по мере необходимости выполнять дополнительные хрупкие трюки ( Сохраните sys.modules["foo"] где-нибудь перед его удалением, после того, как вы импортируете другой файл, поместите этот модуль в другое место и восстановите исходный sys.modules["foo"] - и т. д.), в зависимости от ваших конкретных потребностей. (Конечно, во-первых, избежать столкновений имен было бы почти всегда проще, чем вальсировать вокруг них таким образом; -).

2 голосов
/ 04 декабря 2009

Возможно, вы просто устали от различий между запуском кода в интерактивном интерпретаторе и из файла. Удалите тест для того, чтобы sys.path[0] был пустым (при запуске из файла это не так), и импорт теперь должен работать как вам нужно.

$ more sqlalchemy.py
import sys
print sys.path[0]
sys.path.pop(0)
import sqlalchemy
print sqlalchemy.__file__
$ python sqlalchemy.py 
/Users/nad
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/sqlalchemy/__init__.pyc
$ python
Python 2.6.4 (r264:75706, Oct 28 2009, 20:34:51) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys; print repr(sys.path[0])
''

РЕДАКТИРОВАТЬ: вышеупомянутое применяется, если ваш основной модуль sqlalchemy.py. Если ваш модуль импортирован другим модулем, вам также придется изменить sys.modules, как объясняет Алекс.

2 голосов
/ 04 декабря 2009

Не называйте это sqlalchemy.py?

Серьезно. Я думаю, что эту проблему должен решить абсолютный импорт. В python 2.5 такого не должно быть, но я могу ошибаться

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...