Verwenden des Basisklassenkonstruktors als Factory in Python?

7

Ich benutze den Basisklassenkonstruktor als Factory und ändere die Klasse in diesem Konstruktor / Factory, um die passende Klasse auszuwählen - ist dieser Ansatz eine gute Python-Praxis oder gibt es elegantere Wege?

Ich habe versucht, Hilfe über Metaklassen zu lesen, aber ohne großen Erfolg.

Hier ein Beispiel von dem, was ich mache.

%Vor%

Mit diesem Code kann ich die Instanz von ProjectLocal / ProjectRemote über die Basisklasse Project:

erstellen %Vor%

Ich weiß, dass alternative Möglichkeit ist, Fabric-Funktion zu verwenden, die das Klassenobjekt basierend auf URL zurückgibt, dann sieht der Code ähnlich aus:

%Vor%

Ist meine erste Annäherung nur Geschmackssache oder hat sie versteckte Tücken?

    
bialix 13.02.2009, 10:03
quelle

6 Antworten

12

Ich würde bei der Fabrikfunktion bleiben. Es ist sehr Standard Python und leicht zu lesen und zu verstehen. Sie könnten es allgemeiner machen, mehrere Optionen auf verschiedene Arten zu handhaben, z. B. indem Sie die Diskriminatorfunktion und eine Zuordnung von Ergebnissen zu Klassen übergeben.

Wenn das erste Beispiel funktioniert, ist es eher Glück als Design. Was ist, wenn Sie __init__ in Ihrer Unterklasse definieren möchten?

    
scottynomad 13.02.2009, 10:15
quelle
16

Sie sollten dafür keine Metaklassen benötigen. Sehen Sie sich die Methode __new__ an. Dies ermöglicht es Ihnen, die Kontrolle über die Erstellung des Objekts zu übernehmen, anstatt nur die Initialisierung, und so ein Objekt Ihrer Wahl zurückzugeben.

%Vor%     
Brian 13.02.2009 12:49
quelle
3

Die folgenden Links können hilfreich sein: Ссылка Ссылка

Da Sie auch neue Stilklassen verwenden, ist das Verwenden von __new__ als Factory-Funktion (und nicht in einer Basisklasse, eine separate Klasse ist besser) das, was normalerweise getan wird (soweit ich weiß).

Eine Factory-Funktion ist in der Regel einfacher (wie andere Leute bereits gepostet haben)

Außerdem ist es keine gute Idee, das __class__-Attribut so zu setzen, wie Sie es getan haben.

Ich hoffe, Sie finden die Antwort und die Links hilfreich.

Alles Gute.

    
batbrat 13.02.2009 10:26
quelle
2

Ja, wie von @scooterXL erwähnt, ist die Factory-Funktion in diesem Fall der beste Ansatz, aber ich möchte gerne einen Fall für Fabriken als Klassenmethoden notieren.

Betrachten Sie die folgende Klassenhierarchie:

%Vor%

Nun können Sie Basisobjekte von config dict und von der Konfigurationsdatei erstellen:

%Vor%

Aber Sie können das auch mit ExtendedBase kostenlos machen:

%Vor%

Also kann diese Klassenmethodefabrik auch als Hilfskonstruktor betrachtet werden.

    
andreypopp 23.06.2010 08:53
quelle
1

Normalerweise habe ich dafür eine eigene Fabrikklasse. Auf diese Weise müssen Sie keine Meta-Klassen oder Zuweisungen für self.__class__

verwenden

Ich versuche auch zu vermeiden, das Wissen darüber, welche Klassen für die Erstellung zur Verfügung stehen, in die Fabrik zu bringen. Vielmehr habe ich alle verfügbaren Klassen beim Modulimport werkseitig registrieren lassen. Die give there-Klasse und einige Informationen darüber, wann diese Klasse für die Factory ausgewählt werden soll (dies kann ein Name, eine Regex oder eine aufrufbare Klasse sein) (z. B. eine Klassenmethode der registrierenden Klasse).)

Funktioniert sehr gut für mich und implementiert auch solche Dinge wie Kapselung und das Ausblenden von Informationen.

    
Ber 13.02.2009 10:19
quelle
0

Ich denke, der zweite Ansatz, der eine Factory-Funktion verwendet, ist wesentlich sauberer als die Implementierung Ihrer Basisklasse von ihren Unterklassen abhängig zu machen.

    
unbeknown 13.02.2009 10:14
quelle

Tags und Links