Конфликт имени модуля Python
Я столкнулся с двумя модулями Python, которые нужно импортировать с использованием одного и того же имени модуля, например
import foo
Я знаю, что тот, который я хочу, предоставляет определенные функции (например, foo.bar()
), так есть ли способ циклически переключаться между модулями с тем же именем, пока не найду тот, который предоставляет эти функции? Или нет способа, кроме переименования модуля перед установкой?
Изменить: просто чтобы понять, что я имею в виду, оба модуля находятся внутри пакетов сайта:
site-packages$ ls python_montage-0.9.3-py2.6.egg
EGG-INFO montage
site-packages$ ls montage-0.3.2-py2.6.egg/
EGG-INFO montage
Ответы
Ответ 1
Вот способ:
import imp
import sys
def find_module(name, predicate=None):
"""Find a module with the name if this module have the predicate true.
Arguments:
- name: module name as a string.
- predicate: a function that accept one argument as the name of a module and return
True or False.
Return:
- The module imported
Raise:
- ImportError if the module wasn't found.
"""
search_paths = sys.path[:]
if not predicate:
return __import__(name)
while 1:
fp, pathname, desc = imp.find_module(name, search_paths)
module = imp.load_module(name, fp, pathname, desc)
if predicate(module):
return module
else:
search_paths = search_paths[1:]
Я уверен, что есть некоторые углы, которые я не принимал во внимание, но, надеюсь, это может дать вам некоторую идею.
N.B: Думаю, лучшая идея - просто переименовать ваш модуль, если это возможно.
N.B 2: Как я вижу в вашем отредактированном ответе, к сожалению, это решение не будет работать, потому что два модуля существуют в одном каталоге (site-packages/).
Ответ 2
Есть способы взломать два модуля с одинаковым ограничением имен, но если вы не делаете это просто в образовательных целях, я бы не рекомендовал его. Конечный результат будет запутанным и неподъемным. Я настоятельно рекомендую переименовать один или оба модуля вместо того, чтобы возиться с неясными функциями, связанными с импортом Python.
Ответ 3
Так как python 2.5 (и PEP 328) абсолютный импорт - предпочтительный способ управления модулями в python.
В вашем случае ваше дерево модулей, безусловно, выглядит следующим образом:
/src/first_level/foo
/other_foo
/second_level/foo # with the bar method
Если вы хотите использовать модуль foo с помощью метода bar, используйте это:
import second_level.foo
Ответ 4
Если вы счастливы, что можете определить имена файлов с помощью какой-либо другой эвристики, тогда вы должны иметь возможность использовать imp.load_module для их загрузки отдельно.
См. http://docs.python.org/library/imp.html#imp.load_module
В вашем случае, хотя оба яйца находятся на пути python, я считаю, что яйца делают некоторую магию, благодаря чему каждое яйцо действует как путь. Возможно, вы сможете установить файл яйца в качестве аргумента пути imp.find_module
, чтобы загрузить его отдельно.