多次导入相同的文件名

时间:2010-12-22 15:14:15

标签: python plugins import system

我正在尝试创建一个插件系统,我有一个将所有模块导入数组的函数。

插件布局:

  

PLUGINSDIR /

     

PLUGINSDIR /聊天

     

PLUGINSDIR /聊天/ 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 /聊天

     

PLUGINSDIR /聊天/ main.py

     

PLUGINSDIR /构建

     

PLUGINSDIR /建造/ main.py

我尝试在try语句后添加sys.path.remove(path),但在导入模块后它没有删除路径。

如何正确导入插件?

3 个答案:

答案 0 :(得分:4)

sys.path.append(path)会将插件文件夹附加到sys.path结束。由于Python从前到后搜索sys.path中的文件夹,因此找不到在列表末尾添加其他路径,因为sys.path中前面指定的文件夹中的任何main.py模块实际上会隐藏文件夹中的模块在列表的末尾。相反,您可以使用sys.path.insert(0, path)将新路径添加到列表的前面。

您应该查看Python packages以获得更好地构建插件的方法。

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

使用Python包,脚本中的循环可以通过以下方式轻松实现:

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

答案 1 :(得分:2)

Python模块系统只是处理命名空间的一种非常酷的方式。将具有相同名称的多个模块导入当前命名空间会使其混乱。

无需遍历pluginsDir并导入每个文件,Python将为您执行此操作(来自pluginsDir import *)。如果main.py只进行初始化,则可以将代码移动到pluginsDir/chat/__init__.py

导入插件引用像'pluginsDir.chat'这样的插件被认为是更好的实践。

答案 2 :(得分:0)

你的内部for循环没有缩进,我不明白你的代码运行的原因。修复缩进可能会解决问题。