5

我正在研究一個主要設計指導原則是可擴展性的項目。一類方法 - -如何組織已經工作的插件系統的文件結構?

我通過定義寄存器元類實現的插件系統被加載任何插件的類名(每個類型的插件從核心代碼中定義的特定類繼承,因爲有是應用程序中不同類型的插件)。基本上,這意味着開發者必須定義自己班級的

class PieChart(ChartPluginAncestor): 
    # Duck typing: 
    # Implement compulsory methods for Plugins 
    # extending Chart functionality 

和主程序就知道他的存在,因爲PieChart將被列入註冊插件可在ChartPluginAncestor.plugins列表。

作爲安裝方法類方法,當他們的類別代碼被加載到內存中的所有插件獲得註冊(即類的對象實例化所以即使之前)

該系統的工作足夠™爲我好(雖然我總是願意就如何提高建築!建議),但我現在想知道什麼是管理插件文件的最佳方式(即哪裏以及如何保存包含插件的文件)。

到目前爲止,我正在使用 - 用於開發目的 - 我稱之爲「插件」的軟件包。我將包含插件類的所有* .py文件放在軟件包目錄中,我只需在main.py文件中發佈import plugins,以便所有插件能夠正確掛載。

編輯:傑夫在評論中指出,import plugins包含在套餐的各個模塊課程將不是可用的(我沒有意識到這一點,因爲我是 - 用於調試目的 - 分別導入每個類與from plugins.myAI import AI)。

但是這個系統是唯一的好,而我的開發和測試代碼,如:

  • 插件可能會帶着自己的單元測試,我不希望加載那些在內存中。
  • 所有插件目前都被加載到內存中,但確實有一些插件是相同功能的替代版本,所以您只需要知道您可以在兩者之間切換,但是您只需將它們加載到內存中即可你從配置窗格中選擇的一個。
  • 在某些時候,我希望有一個安裝插件的雙重位置:系統範圍的位置(例如/usr/local/bin/以下的某處)和用戶特定的位置(例如/home/<user>/.myprogram/以下的某處)。

所以我的問題是真的 - 也許 - 三:

  1. 插件容器:什麼是最明智的選擇。我的目標是什麼?單個文件?包?一個簡單的.py文件目錄?)
  2. 意識到插件的存在,而不一定要加載(導入)它們:什麼是使用Python自省的聰明方法?
  3. 將插件放置在兩個不同的位置:是否有標準方法/最佳實踐(至少在gnu/linux下)來做到這一點?
+1

我會認爲'import plugins'只會加載包而不是包中的模塊。 – 2010-07-29 13:36:21

+0

這是我正在尋找的提示! :) – mac 2010-08-02 12:51:51

回答

3

這個問題很難解決,因爲需求很複雜。 無論如何,我會嘗試一些建議。

關於

在兩個不同的地點 配售插件:是有一個標準的方法/ 最佳實踐(GNU/Linux下,在 至少)這樣做呢?

一個好方法是virtualenv。 Virtualenv是一個構建「獨立」python安裝的python模塊。讓單獨的項目一起工作是更好的方式。 你會得到一個全新的網站包,你可以把你的插件與相關的項目模塊。

試試看:http://pypi.python.org/pypi/virtualenv

插件容器:什麼是我的目標是最 明智的選擇?單個 文件?包? ?的 .py文件一個簡單的目錄)

一個好的方法是一個Python包,它可以做一個「自注冊」導入時:簡單的包目錄中定義一個適當的初始化的.py

的實例可以是http://www.qgis.org/wiki/Writing_Python_Plugins 和這裏所描述的API http://twistedmatrix.com/documents/current/core/howto/plugin.html

參見http://pypi.python.org/pypi/giblets/0.2.1

內臟是一個簡單的插件系統 基於組件架構 Trac。簡而言之,內臟消息允許您聲明接口並發現 實現它們的組件,而不需要 耦合。

內臟還包括基於文件路徑或入口點 以及靈活的手段來管理 哪些組件啓用或禁用 在應用程序中的插件發現 。

+0

感謝您的回答和各種鏈接(+1)。我之前讀過內臟雜誌,但我不太喜歡它的設計。鴨打字很好,內省很好。不得不宣佈「暗示」是...好吧,不那麼好!另一方面,它確實通過路徑發現插件,所以我可能會查看它的源代碼並檢查它是如何實現跨平臺兼容性的。此外,白名單/黑名單功能對我也很有幫助。而另一方面,Virtualenv遠遠超出了我的需求。我對單一環境感到滿意,我只是想爲不同的用戶提供不同的搜索插件路徑! – mac 2010-08-02 12:17:31

1

我也有一個插件系統有三種類型的插件,但我並沒有聲稱做得很好。你可以看到一些細節here

對於內部插件,我有一個包(例如,MethodPlugins),在這個包中是每個插件的模塊(例如,MethodPlugins.IRV)。下面是我如何加載插件:

  1. 裝入包(import MethodPlugins

  2. 使用pkgutil.iter_modules加載所有模塊存在(例如,MethodPlugins.IRV

  3. 所有插件從下降通用基類,所以我可以使用__subclassess__來識別它們。

我相信,這將讓你認識插件,而無需實際加載它們,但我不這樣做,我只是加載它們。

對於外部插件,我有一個指定的目錄,用戶可以放置它們,我使用os.listdir來導入它們。用戶需要使用正確的基類,以便我可以找到它們。

我也有興趣改善這一點,但它也適用於我。 :)

+0

謝謝你的回答。最好的建議(給我提供了我期待的新視角/信息片段,儘管你給我提供了你的評論),我已經急急地從'plugins.betterai import AI'寫下了'而且沒有意識到如果我簡單地寫了'import plugins'那個類是無法訪問的,我想我會把我的插件保存爲包,並檢查你上面發佈的鏈接,看看你是如何做自己的系統的。一個工作解決方案。謝謝! – mac 2010-08-02 12:55:54