Hi,
ich schreibe gerade an einem kleinen Programm und sozusagen als
Fingerübung bzw. aus Interesse wollte ich das Programm durch
Plugins erweiterbar gestalten. Letztlich soll der Benutzer .py-Dateien
in einen Plugin-Ordner speichern und das Programm diese Plugins laden
und eine bestimmte Funktion ausführen, die die API spezifiziert.
Soweit so schön, es gibt ja auch ein paar Anleitungen dafür im Netz,
ich bin soweit dieser hier gefolgt:
http://aroberge.blogspot.com/2008/12/plugins-part-3-simple-class-based.html
Allerdings verhält sich
__import__ nicht so, wie ich mir
das vorstelle, oder es im Tutorial beschrieben ist.
Eigentlich sollte ja das per Variable übergebene Modul geladen werden,
in den Modulen wiederum sollen sich Tochterklassen der Plugin-Klasse
befinden, die dann über
__subclasses__() angesprochen werden können.
Nun funktioniert es soweit, dass ich die entsprechenden Modulnamen
geparst bekomme und
__import__ auch fehlerfrei aufgerufen wird. Allerdings
sind die darin enthaltenen Klassen danach im Programm nicht bekannt.
Laut sys.modules sind die Module allerdings importiert.
Ich vermute ein wenig, dass es sich so verhält, dass der Aufruf von
__import__ äquivalent zu
import modulName ist, ich
aber eher etwas bräuchte wie
from modulName import *.
Hier sind mal die relevanten Zeilen an Code:
plugin_dir = "/home/markus/svn/netray/plugins/"
plugin_files = [x[:-3] for x in os.listdir(plugin_dir) \
if (x.endswith(".py") and \
not x.startswith("__")) \
and not x == "netrayPlugin.py"]
sys.path.insert(0, plugin_dir)
for plugin in plugin_files:
mod = __import__(plugin)
print NetrayPlugin.__subclasses__()
for plugin in NetrayPlugin.__subclasses__():
if hasattr(plugin, "getEntry"):
self.menu.addAction(plugin.getEntry(self))
elif hasattr(plugin, "getMenu"):
self.menu.addMenu(plugin.getMenu(self))
Eine kleines Testplugin, welches einfach nur einen Eintrag in einem Menü
darstellen soll, sieht dann so aus:
class std(NetrayPlugin):
def getEntry(self, parent):
fooaction = QAction("Foo", parent)
return fooaction
Wie gesagt, es handelt sich um prototyp-code also bitte keine bashes wegen
fehlender Fehlerbehandlung, hardgecodeten Verzeichnissen etc. 😉
Lg,
Vrob