Конфликт имени модуля 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

person astrofrog    schedule 09.05.2011    source источник
comment
Есть ли что-то, что не позволяет вам переименовать имя вашего модуля? потому что, насколько я знаю, это легко решить эту банку проблем :)   -  person mouad    schedule 09.05.2011
comment
Где находятся эти модули по пути? У вас есть один в каталоге пакетов вашего сайта, а другой в текущем каталоге (файла импорта)? В этом случае вы можете использовать абсолютный импорт для решения проблемы неоднозначности.   -  person Boaz Yaniv    schedule 09.05.2011
comment
Оба модуля находятся внутри одного из каталогов пакетов сайтов - я отредактировал вопрос, чтобы сделать его более понятным.   -  person astrofrog    schedule 09.05.2011


Ответы (4)


Вот способ:

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

Бьюсь об заклад, есть некоторые моменты, которые я не принял во внимание, но, надеюсь, это может дать вам некоторое представление.

NB: Я думаю, что лучше всего просто переименовать ваш модуль, если это возможно.

NB 2: Как я вижу в вашем отредактированном ответе, к сожалению, это решение не будет работать, потому что два модуля находятся в одном каталоге (site-packages/).

person mouad    schedule 09.05.2011
comment
+1 за __import__, не знал, что вы можете сделать импорт без операторов, и это то, что мне нужно. - person keflavich; 13.12.2012

Есть способы обойти два модуля с ограничением на одно и то же имя, но если вы не делаете это просто в образовательных целях, я бы не рекомендовал этого делать. Конечный результат будет запутанным и неуправляемым. Я настоятельно рекомендую переименовать один или оба модуля вместо того, чтобы возиться с малоизвестными функциями, связанными с импортом Python.

person Cosmin Stejerean    schedule 09.05.2011

Поскольку в Python 2.5 (и PEP 328) абсолютный импорт является предпочтительным способом управление модулями в питоне. В вашем случае ваше дерево модулей, безусловно, выглядит так:

/src/first_level/foo
                /other_foo
    /second_level/foo # with the bar method

Если вы хотите использовать модуль foo с методом bar, используйте это:

import second_level.foo
person Cédric Julien    schedule 09.05.2011
comment
Я не думаю, что смогу это сделать, потому что имя модуля верхнего уровня такое же - я отредактировал вопрос, чтобы уточнить это. - person astrofrog; 09.05.2011

Если вы довольны тем, что можете определить имена файлов с помощью какой-либо другой эвристики, тогда вы сможете использовать imp.load_module для их загрузки по отдельности.

См. http://docs.python.org/library/imp.html#imp.load_module

В вашем случае, хотя оба яйца находятся на пути питона, я считаю, что яйца творят чудеса, когда каждое яйцо действует как путь. Возможно, вы сможете установить для файла яйца в качестве аргумента пути значение imp.find_module, чтобы загрузить их отдельно.

person Glenjamin    schedule 09.05.2011