2017-10-13 3 views
1

Ich habe einige Module, die in verschiedenen Verzeichnissen sind. Wie kann ich Klassen in diesen module nur dann instanziieren, wenn die Klassen Unterklassen von ParentClass sind? Im Grunde versuche ich so etwas wie dies unten und wissen wollen, wie ich child_class_name implementieren DiesesInstantiate Python-Unterklassen aus verschiedenen Verzeichnissen

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

Ich verstehe nicht, was Sie brauchen genau, wie überprüft man, ob 'ChildClass' eine Unterklasse ist? oder Schleife durch alle Klassenobjekte im Modul, um herauszufinden, welches eine Unterklasse ist? – PRMoureu

+0

Letztere, durchlaufen Sie alle Klassenobjekte im Modul, um herauszufinden, welche eine Unterklasse ist, damit ich 'ChildClass' erstellen kann. Danke! –

Antwort

2

sollte mit diesem Verständnis Liste arbeiten:

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

vars(module).values() gibt alle Objekte im Modul leben. Sie können die Unterklassen mit issubclass(obj,ParentClass) filtern.

(isinstance hilft nur Klasse Objekte zu filtern.)


childclasses eine Liste von Klassen, die Sie direkt instanziieren, ohne getattr mit:

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

EDIT:

Um zu vermeiden, ParentClass Sie die Liste in eine Reihe umwandeln kann, und entfernen Sie es, wenn es vorhanden ist:

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

oder einen anderen Test im Verständnis hinzufügen:

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

Das ist eine schöne Lösung! Nur eine Frage, wie kann ich 'ParentClass' von' Childclasses' entfernen, das aussieht wie '[, ]'? Ich denke, das liegt daran, dass in jedem Kind-Modul "from parent_class" ParentClass im oberen Bereich ist. –

Verwandte Themen