我正在編寫一個應用程序。沒有花哨的圖形用戶界面:不管什麼,只是一個普通的舊控制檯應用該應用程序可以稱爲App,需要能夠在啓動時加載插件。因此,很自然,我創建了一個類的插件繼承:動態導入模塊,然後從所述模塊實例化具有某個基類的對象
class PluginBase(object):
def on_load(self):
pass
def on_unload(self):
pass
def do_work(self, data):
pass
的想法是,在啓動時,應用程序將通過當前目錄,包括子目錄走,尋找包含類本身是的子模塊PluginBase
。
更多代碼:
class PluginLoader(object):
def __init__(self, path, cls):
""" path=path to search (unused atm), cls=baseclass """
self.path=path
def search(self):
for root, dirs, files in os.walk('.'):
candidates = [fname for fname in files if fname.endswith('.py') \
and not fname.startswith('__')]
## this only works if the modules happen to be in the current working dir
## that is not important now, i'll fix that later
if candidates:
basename = os.path.split(os.getcwd())[1]
for c in candidates:
modname = os.path.splitext(c)[0]
modname = '{0}.{1}'.format(basename, modname)
__import__(mod)
module = sys.modules[mod]
經過search
最後一行,我想以某種方式一)發現新加載的模塊中的所有類,b)檢查如果一個或多個這些類是子類PluginBase
和c)(如果b)實例化那些/這些類並添加到應用程序的加載模塊列表。
我試過issubclass
和其他的各種組合,然後是激烈的dir
:ing和約一個小時的慌亂Google搜索。我找到了類似的方法,我的here,我試着複製粘貼,但得到一個錯誤,說Python不支持通過文件名導入,在這一點上我有點失去了專注力,因此,這篇文章被寫了。
我在我的智慧結束在這裏,所有的幫助表示讚賞。
它的工作幾乎完美,謝謝!我添加了`和cls .__ name__!= base .__ name__`,以避免將基類添加到子類列表中。 – manneorama 2011-01-25 21:03:16