2017-10-13 77 views
1

我有一些模塊位於不同的目錄中。只有當這些類是ParentClass的子類時,我如何在這些module中實例化類?從本質上講,我想是這樣的下面,想知道怎樣才能實現child_class_name實例化來自不同目錄的Python子類

from importlib.machinery import SourceFileLoader 
from parent_class import ParentClass 

instances = [] 

script_path1 = r'/some/different/directory/some_child.py' 
script_path2 = r'/some/different/directory/another_child.py' 

for script_path in [script_path1, script_path2]: 

    module = SourceFileLoader('module', script_path).load_module() 

    child_class_name = "If a class in this module is a subclass of ParentClass" 

    ChildClass = getattr(module, child_class_name) 
    instances.append(ChildClass()) 
+1

我不明白你需要什麼確切地說,如何檢查'ChildClass'是否是一個子類?或循環遍歷模塊中的所有類對象以查找哪一個是子類? – PRMoureu

+0

後者循環遍歷模塊中的所有類對象以找到哪一個是子類,以便我可以創建'ChildClass'謝謝! –

回答

2

這應該與此理解名單的工作:

childclasses = [obj for obj in vars(module).values() 
        if isinstance(obj,type) and issubclass(obj,ParentClass)] 

vars(module).values()返回居住模塊中的所有對象。

然後,您可以使用issubclass(obj,ParentClass)篩選子類。

isinstance只會有助於過濾類的對象。)


childclasses是的,你可以直接實例化類的列表,而無需使用getattr

for ChildClass in childclasses: 
    instances.append(ChildClass()) 

編輯

爲了避免ParentClass您可以將列表轉換爲一組,並刪除它,如果它存在:

childclasses = set([obj for obj in vars(module).values() 
         if isinstance(obj,type) and issubclass(obj,ParentClass)]) 
if ParentClass in childclasses: 
    childclasses.remove(ParentClass) 

或在修真再添測試:

childclasses = [obj for obj in vars(module).values() 
         if isinstance(obj,type) and 
         issubclass(obj,ParentClass)and 
         obj is not ParentClass ] 
+1

這是一個美麗的解決方案!只有一個問題,我如何從'childclasses'中刪除'ParentClass',看起來像'[]'?我認爲這是因爲在每個子模塊中都有'從頂層的parent_class導入ParentClass'。 –