同名文件的多次导入
我正在尝试创建一个插件系统,并且我有一个函数可以把所有模块导入到一个数组里。
插件的布局如下:
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 个回答
你的内层循环没有缩进,我不知道你的代码为什么还能运行。调整一下缩进可能就能解决这个问题。
Python的模块系统是一种很酷的方式来管理命名空间。把多个同名的模块导入到当前命名空间会让它变得混乱。
你不需要手动去遍历插件目录并导入每个文件,Python会为你处理这些事情(可以用从插件目录导入所有内容的方式:from pluginsDir import *
)。如果你的main.py文件只是用来初始化一些东西,你可以把这些代码移动到pluginsDir/chat/__init__.py
里。
像这样导入插件目录,使用'pluginsDir.chat'的方式被认为是更好的做法。
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)