2017-10-13 57 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'。 –