2011-06-29 29 views
1

我的程序分爲兩部分:處理用戶界面和其他「主程序」內容的引擎,以及一組插件,它們提供了處理特定輸入的方法。插件設計問題

每個插件都是在自己的模塊中編寫的,並提供了一個函數,允許我向插件發送數據和從插件中檢索數據。

該函數的名稱在所有插件中都是相同的,所以我需要的是確定要調用哪一個,然後該插件將處理其餘部分。

我已經放在所有子文件夾中的插件,寫了__ init__.py是進口的每個插件,然後我導入文件夾(我認爲這就是所謂的一包?)

反正目前我明確地告訴它要導入什麼(基本上是「導入這個」,「導入」)。有沒有辦法讓我編寫它,以便它將導入該插件的文件夾中的所有內容,以便我可以添加額外的插件而無需編輯init文件?

回答

2

這裏是我用來做這個代碼:

def _loadPackagePlugins(package): 
    "Load plugins from a specified package." 
    ppath = package.__path__ 
    pname = package.__name__ + "." 
    for importer, modname, ispkg in pkgutil.iter_modules(ppath, pname): 
    module = __import__(modname, fromlist = "dummy") 

從雅各布的回答的主要區別是,它採用pkgutil.iter_modules代替os.listdir。我曾經使用os.listdir,並改爲這樣做,但我不記得爲什麼。當我使用py2exe和py2app打包我的應用程序時,os.listdir可能會失敗。

+0

這將會很有用。謝謝 – MxyL

+0

奇怪,這是一個奇怪的模塊,我仍然喜歡答案。 –

1

你可以總是有一個叫做插件的字典,使用__import__導入模塊並以這種方式存儲它們。

例如

plugins = {} 
for plugin in os.listdir('plugins'): 
    plugin = plugin.split()[0] 
    plugins[plugin] = __import__(plugin) 

這是假定每個插件都是單個文件。我個人的東西,看起來每個文件夾中的文件__run__.py,就像一個__init__.py走在一個包,那麼就是一個插件,該代碼會看起來更像是這樣的

for root, dirs, files in os.walk('.'): 
    for dir in dirs: 
     if "__run__.py" in os.listdir(os.path.join(root, dir)): 
      plugins[dir] = __import__(dir) 

未經測試編寫的代碼。因人而異

+0

比具有單個文件夾或硬編碼多個文件夾名稱更靈活。好主意。 – MxyL