2016-01-21 47 views
-2

我有一個Python應用程序,我試圖在基於學校名稱的類中動態調用函數。這些學校是在單獨的模塊中/學校專業目錄:在Python中動態調用基於類名稱的函數

def __init__(self): 
    self.Schools = [] 
    self.Students = [] 

def Load_Selected_Schools(self): 
    files = glob.glob('schools/*.py') 
    for f in files:   
     self.Schools.append(self.Load_School(f)) 

def Load_School(self, path): 
    modname = os.path.splitext(os.path.basename(path))[0] 
    mod = imp.load_source(modname, path) 
    return mod 

每個單獨的學校模塊看起來是這樣的:

class xyz(object): 
    def Get_School_Name(self): 
     return "xyz" 

    def Get_Students(self): 
     Students = [] 
     #code removed for clarity 
     #But basically I create a bunch of Student objects 
     Student = {} 
     Student['Name'] = "John Smith" 
     Student['School'] = "xyz"] 
     return Students 

    def Get_Student_Details(self): 
     # This will return student details 

在這一點上我最終有像這樣的項目的數組:

{ Name: "John Smith", School: "xyz" } 
{ Name: "Bob Jane", School: "abc" } 
{ Name: "Jane Davis", School: "xyz" } 
... etc 

我想要做的就是通過這個數組迭代,然後調用Get_Student_Details功能正確的學校。因此,數組中的第一個條目應該調用xyz類中的Get_Student_Details函數,abc類中的第二個函數,xyz類中的第三個函數,每次傳入Name參數。

我對Python相當陌生,不確定如何去調用正確的類。

+0

學校不應該是一個新的學校子類,他們應該是學校的例子。這也是爲數據庫量身定製的。 –

+0

(聳肩)我沒有讓你失望。 –

回答

1

我不知道我完全理解問題,但是有一個映射形式「學校」 - >學校對象,而不是學校名稱可能會有所幫助。

在每個有道詞典您有

{名稱:「約翰·史密斯」,學校:}

然後,你可以簡單地說,遍歷數組,訪問與「學校」相關聯的值鍵,然後在正確的類上調用get_student_details。

+0

這看起來很理想 - 但我該如何「在正確的類上調用get_student_details」? – Evonet

+1

我認爲他正在嘗試延遲加載模塊;在模塊加載之前他不能引用該類,並且除非需要,否則他不想加載該模塊。 –

1

可以動態調用模塊中的類與GETATTR:

class_ = getattr(module, 'xyz') 
class_().Get_School_Name() 

我將存儲在字典中,而不是其中的關鍵標誌着學校名稱列表學校(假設你有每所學校的單一模塊)。然後你可以做這樣的事情。

for student in student_list: 
    class_ = getattr(self.Schools[student["School"]], student["School"]) 
    class_().Get_Student_Details() 

備註:

  • 你需要知道哪些學校是哪個模塊中雖然。因爲沒有對象信息被用來(與相同Get_Students)
  • 下駱駝通常用於函數和變量名
  • 方法Get_Student_Details應進行靜態
+0

工作原理 - 儘管學校名稱可能是「XYZ學校」,但模塊名稱是「xyzschool」,但每個模塊都有一所學校。關於靜態的好點子 – Evonet