同名文件的多次导入

0 投票
3 回答
1835 浏览
提问于 2025-04-16 08:54

我正在尝试创建一个插件系统,并且我有一个函数可以把所有模块导入到一个数组里。

插件的布局如下:

pluginsDir/

pluginsDir/chat

pluginsDir/chat/main.py

这是一个用来查找和导入插件的函数:

if os.path.exists(pluginsDir):
    for path, dirArray, fileArray in os.walk(pluginsDir):
        for fileName in fileArray:
            if fileName == "main.py":
            sys.path.append(path)
            try:
                plugins.append(__import__("main"))
            except:
                print 'Could not import plugin, "'+path+'": plugin contains errors or is not a real plugin.'

如果我只有一个插件,这样做是没问题的,但当我有多个插件时,它总是导入第一个检测到的插件。

插件的布局如下:

pluginsDir/

pluginsDir/chat

pluginsDir/chat/main.py

pluginsDir/build

pluginsDir/build/main.py

我尝试在我的尝试语句后面加上sys.path.remove(path),但在我已经导入模块后,它并没有把路径移除。

我该怎么做才能正确导入我的插件呢?

3 个回答

0

你的内层循环没有缩进,我不知道你的代码为什么还能运行。调整一下缩进可能就能解决这个问题。

2

Python的模块系统是一种很酷的方式来管理命名空间。把多个同名的模块导入到当前命名空间会让它变得混乱。

你不需要手动去遍历插件目录并导入每个文件,Python会为你处理这些事情(可以用从插件目录导入所有内容的方式:from pluginsDir import *)。如果你的main.py文件只是用来初始化一些东西,你可以把这些代码移动到pluginsDir/chat/__init__.py里。

像这样导入插件目录,使用'pluginsDir.chat'的方式被认为是更好的做法。

4

sys.path.append(path) 这个命令会把插件文件夹添加到 最后 的位置。因为 Python 在查找文件夹时是从 sys.path 的前面开始往后找的,所以如果你把新的路径加到列表的最后,之前在 sys.path 中的文件夹里的模块就会“遮住”后面文件夹里的模块。换句话说,Python 会优先找到前面的模块,而忽略后面的。为了避免这个问题,你可以使用 sys.path.insert(0, path),这样可以把新的路径加到列表的最前面。

你可以查看 Python 包,这样可以更好地组织你的插件。

plugindir/
    __init__.py
    plugin1/
        __init__.py
    plugin2/
        __init__.py

使用 Python 包的话,你的脚本中的循环可以很简单地实现:

sys.path.insert(0, path_to_plugindir)
for folder in dirArray:
    __import__(folder)

撰写回答