Reputation: 1150
I am trying to create a plugin system and I have a function that imports all the modules into an array.
Layout of Plugins:
pluginsDir/
pluginsDir/chat
pluginsDir/chat/main.py
And this is the function that finds and imports the plugins:
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.'
This is fine if I only have one plugin but when I have multiple plugins it keeps importing the first plugin it detects.
Layout of Plugins:
pluginsDir/
pluginsDir/chat
pluginsDir/chat/main.py
pluginsDir/build
pluginsDir/build/main.py
I've tried to addsys.path.remove(path)
after my try statement, but it doesn't remove the path after I have already imported the module.
What can I do to import my plugins correctly?
Upvotes: 0
Views: 1851
Reputation: 77281
The Python module system is just a very cool way to handle namespaces. Importing several modules with the same name to your current namespace will clutter it.
No need to traverse the pluginsDir and import each file, Python will do that for you (from pluginsDir import *). If main.py does only initialization stuf you can move the code to pluginsDir/chat/__init__.py
.
Import pluginsDir refering to your plugins like 'pluginsDir.chat' is considered better pratice.
Upvotes: 2
Reputation: 1799
sys.path.append(path)
will attach the plugin folder to the end of sys.path
. Since Python searches folders in sys.path
from front to back, appending additional paths to the end of the list will not be found because any main.py modules in folder specified earlier in sys.path
will essentially hide modules in folders at the end of the list. Instead, you could use sys.path.insert(0, path)
to add new paths to the front of the list.
You should look at Python packages for a way to better structure the plugins.
plugindir/
__init__.py
plugin1/
__init__.py
plugin2/
__init__.py
With Python packages, the loop in your script can be easily implemented with:
sys.path.insert(0, path_to_plugindir)
for folder in dirArray:
__import__(folder)
Upvotes: 4
Reputation: 2613
Your inner for loop is not indented, I don't see why your code runs at all. Fixing the indentation might fix the problem.
Upvotes: 0