Python模块名冲突

10 投票
4 回答
9121 浏览
提问于 2025-04-16 17:17

我遇到了两个Python模块,它们的名字是一样的,比如:

import foo

我知道我想要的那个模块提供了一些特定的功能(比如 foo.bar()),那么有没有办法在这些同名模块中循环查找,直到找到那个提供这些功能的模块?还是说除了在安装之前重命名模块之外没有其他办法?

补充说明一下,我的意思是,这两个模块都在site-packages文件夹里:

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

4 个回答

0

从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
3

有一些方法可以绕过两个模块同名的限制,但除非你只是为了学习,否则我不建议这么做。这样做的结果会让人感到困惑,而且不容易维护。我强烈建议你重命名其中一个或两个模块,而不是去搞一些复杂的Python导入相关的特性。

6

这里有一种方法:

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

我敢打赌还有一些细节我没有考虑到,但希望这能给你一些启发。

注意:我觉得最好的办法就是如果可以的话,直接重命名你的模块。

注意2:根据我在你编辑后的回答中看到的,遗憾的是这个解决方案行不通,因为这两个模块在同一个目录下(site-packages/)。

撰写回答