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?
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?
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.
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.
Normalerweise habe ich dafür eine eigene Fabrikklasse. Auf diese Weise müssen Sie keine Meta-Klassen oder Zuweisungen für self.__class__
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.
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.