我正在開發一個PyQT應用程序。此應用程序能夠從數據庫加載一些數據,然後對這些數據進行各種分析。所有這些工作。但由於分析可能相當複雜,並且由於不會是唯一的用戶,我不得不開發一個帶有用戶定義腳本的系統。 基本上,有一個文本編輯器,用戶可以編寫自己的小型Python腳本(帶函數)。然後,用戶可以通過將文件作爲模塊(在應用程序內)加載來保存腳本或執行它。如何在整個應用程序中訪問變量/對象?
這裏有一個我的應用程序的簡化版本。
應用程序的核心是My_apps.py 和插件都在這裏同一個文件夾即Plugin_A.py
這是My_apps.py的代碼:
import sys,os
class Analysis(object):
def __init__(self):
print "I'm the core of the application, I do some analysis etc..."
def Analyze_Stuff(self):
self.Amplitudes_1=[1,2,3,1,2,3]
class Plugins(object):
def __init__(self):
newpath = "C:\Users\Antoine.Valera.NEUROSECRETION\Desktop\Model" #where the file is
sys.path.append(newpath)
Plugin_List=[]
for module in os.listdir(newpath):
if os.path.splitext(module)[1] == ".py":
module=module.replace(".py","")
Plugin_List.append(module)
for plugin in Plugin_List:
a=__import__(plugin)
setattr(self,plugin,a)
def Execute_a_Plugin(self):
Plugins.Plugin_A.External_Function(self)
if __name__ == "__main__":
Analysis=Analysis()
Plugins=Plugins()
Plugins.Execute_a_Plugin()
這裏是Plugin_A.py
def External_Function(self):
Analysis.Analyze_Stuff()
print Analysis.Amplitudes_1
的代碼示例爲什麼會:
Traceback (most recent call last):
File "C:\Users\Antoine.Valera.NEUROSECRETION\Desktop\Model\My_Apps.py", line 46, in <module>
Plugins.Execute_a_Plugin()
File "C:\Users\Antoine.Valera.NEUROSECRETION\Desktop\Model\My_Apps.py", line 37, in Execute_a_Plugin
Plugins.Plugin_A.External_Function(self)
File "C:\Users\Antoine.Valera.NEUROSECRETION\Desktop\Model\Plugin_A.py", line 8, in External_Function
Analysis.Analyze_Stuff()
NameError: global name 'Analysis' is not defined
,但如果我添加了2線以下行,而不是Plugins.Execute_a_Plugin()
Analysis.Analyze_Stuff()
print Analysis.Amplitudes_1
那麼,它的工作原理。
我該如何向每個動態加載的插件指出他必須使用Analysis中已有的變量/對象?爲什麼我無法從插件中打印Analysis.Amplitudes_1?
謝謝!
好了,該解決方案運行良好!也許是最後一點。在我的申請中,有6個重要的課程。是否有一種簡單的方法可以自動將它們傳遞給插件函數,而無需單獨命名所有這些函數? (我可以將它們包含在* kargs或** kwargs中)。我嘗試了ARG = [Analysis,Class2,Class3,Class4,Class5,Class6],然後 'def Execute_a_Plugin(self):' 'plugins.Plugin_A.External_Function(self,Analysis,Class2,Class3,Class4,Class5,Class6 )' 我可以調用'plugins.Plugin_A.External_Function(self,* ARG)',它的工作
。但我更希望在函數定義中有* ARG。 – Vantoine
@Vantoine。你可以有一個容器類,其所有其他類實例都是屬性,然後將容器傳遞給插件。 – ekhumoro
這個怎麼樣? (它可以工作,但它可能不是最清潔的方式):在程序開始時,我在Class_List中添加Class_List = [Navigate,Requete,Analysis,Main,Infos,Mapping] : setattr __builtin __,Class .__ name __,Class)'然後,加載一個插件:'setattr(sys.modules [__ name __],plugin,__ import __(plugin))',插件是加載插件的名稱。 – Vantoine