Python: как выбрать модуль для импорта, если они названы одинаково - PullRequest
6 голосов
/ 11 августа 2009

Допустим, я нахожусь в файле с именем openid.py, и я делаю:

from openid.consumer.discover import discover, DiscoveryFailure

У меня есть модуль openid на моем pythonpath, но интерпретатор, похоже, пытается использовать мой файл openid.py. Как я могу получить версию библиотеки?

(Конечно, было бы неплохо что-то, кроме очевидного ответа «переименовать файл»).

Ответы [ 5 ]

9 голосов
/ 11 августа 2009

По этой причине абсолютный импорт был выбран в качестве нового поведения по умолчанию. Тем не менее, они еще не по умолчанию в 2.6 (может быть, в 2.7 ...). Вы можете узнать их поведение сейчас, импортировав их из будущего:

from __future__ import absolute_import

Вы можете узнать больше об этом в PEP, отмеченном Ником или (я думаю, легче понять) в документе «Что нового в Python 2.5» .

3 голосов
/ 11 августа 2009

Переименуйте его . Это идея пространства имен. ваш openid может быть субмодулем в вашем верхнем модуле project. ваш email будет конфликтовать с верхним модулем email в стандартной памяти.

, поскольку ваш openid не универсален, он обеспечивает особый случай для вашего проекта.

2 голосов
/ 11 августа 2009

Я не буду вдаваться в полемику по поводу переименования, а вместо этого сосредоточусь на том, чтобы показать вам, как делать то, что вы хотите (будь то «хорошо для вас» или нет ;-). Решение не сложное ...

Просто установите __path__! Небольшая демонстрация:

$ mkdir /tmp/modules /tmp/packages
$ mkdir /tmp/packages/openid
$ echo 'print "Package!"' > /tmp/packages/openid/__init__.py
$ gvim /tmp/modules/openid.py
$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid'
Module!
Package!

здесь показан модуль openid, управляющий импортом одноименного пакета , хотя путь к модулю указывается ранее в sys.path, и sys.modules['openid'] явно уже установлено в то время. И весь «секрет» в простом коде openid.py ...:

print "Module!"
__path__ = ['/tmp/packages']
import openid

без назначения __path__, конечно, он будет излучать только Module!.

Также работает для импорта подмодулей внутри пакета, конечно. Есть:

$ echo 'print "Submod!"' > /tmp/packages/openid/submod.py

и измените последнюю строку openid.py на

from openid import submod

и вы увидите:

$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid'
Module!
Package!
Submod!
$ 
1 голос
/ 11 августа 2009

Вы можете использовать относительный или абсолютный импорт (в зависимости от специфики вашей ситуации), который рассматривается в PEP 328 в последнее время. Конечно, серьезно, вы не должны создавать конфликты имен, подобные этому, и должны переименовывать ваш файл.

0 голосов
/ 11 августа 2009

Вы можете попробовать перетасовать sys.path, чтобы переместить интересные каталоги вперед, прежде чем выполнять импорт.

...