2013-08-19 2 views
7

Gibt es eine Möglichkeit, alle Klassen von einem Python-Modul in eine Liste von namenlosen Objekten zu initialisieren?Initialisieren Sie alle Klassen in einem Modul in namenlose Objekte in einer Liste

Beispiel Ich habe ein Modul rules, die alle untergeordneten Klassen aus einer Klasse-Regel enthält. Dieser Grund, ich bin sicher, sie werden alle ein Verfahren run() implementieren und werden ein Attribut name haben, die während des Gesprächs von __init__

ich eine Liste von Objekten aus diesen Klassen dynamisch initiiert haben möchte generiert werden. Mit dynamisch initialisiert bedeutet das, dass sie nicht explizit benannt werden müssen.

Die Fragen sind:

Ist es möglich, durch alle Klassen in einem Modul zu wiederholen?

Kann ein namenloses Objekt initiiert werden?

Antwort

8

Es gibt mindestens zwei Ansätze, die Sie verwenden können. Sie können alle Unterklassen einer Klasse abrufen, indem Sie die Methode __subclasses__() einer Klasse aufrufen. Also, wenn Ihr Elternklasse Rule genannt wird, könnte man nennen:

rule_list = [cls() for cls in Rule.__subclasses__()] 

Diese Sie geben alle Subklassen von Rule, und sie nicht auf die, die in einem bestimmten Modul gefunden begrenzen.

Wenn Sie ein Handle zu Ihrem Modul haben, können Sie über dessen Inhalt iterieren. Wie so:

import rule 
rule_list = [] 
for name in dir(rule): 
    value = getattr(rule, name) 
    if isinstance(value, type) and issubclass(value, Rule): 
     rule_list.append(value()) 

Leider issubclassTypeError wirft, wenn Sie es ein Objekt geben, die nicht eine Klasse als erstes Argument ist. Also musst du irgendwie damit umgehen.

EDIT: Umgang mit der issubclass Eigenart per @ Blckknght Vorschlag.

+0

Besser als meine Antwort. Sie können 'inspect.isclass()' verwenden, um 'TypeError' zu vermeiden. –

+0

@AntonisChristofides True, Sie können 'inspect.isclass()' als Filter verwenden. Ich versuche jedoch zu vermeiden, irgendetwas aus dem "inspect" -Modul im Produktionscode zu verwenden. –

+0

Sie können auch 'isinstance (value, type)' verwenden, um sicherzustellen, dass Sie eine Klasse haben. (Sie müssen auch nach 'types.ClassType' suchen, wenn Sie Klassen im alten Stil unterstützen müssen, aber ich würde diese stattdessen einfach meiden.) – Blckknght

Verwandte Themen