Problem
Ich arbeite an einem Python-Projekt, dessen Hauptklasse ein bisschen " God Object " ist. Es gibt so verdammt viele Attribute und Methoden!
Ich möchte die Klasse umgestalten.
Bisher…
Für den ersten Schritt möchte ich etwas relativ Einfaches tun; Aber als ich den einfachsten Ansatz ausprobierte, wurden einige Tests und vorhandene Beispiele gebrochen.
Grundsätzlich hat die Klasse eine lange Liste von Attributen - aber ich kann sie mir klar ansehen und denken: "Diese 5 Attribute sind verwandt ... Diese 8 sind auch verwandt ... und dann gibt es den Rest."
getattr
Ich wollte im Grunde nur die verwandten Attribute in einer diktartigen Hilfsklasse gruppieren. Ich hatte das Gefühl __getattr__, ideal für den Job zu sein. Also habe ich die Attribute in eine separate Klasse verschoben und natürlich __getattr__seine Magie perfekt umgesetzt ...
Am ersten .
Aber dann habe ich versucht, eines der Beispiele auszuführen. Die Beispielunterklasse versucht, eines dieser Attribute direkt (auf Klassenebene) festzulegen . Da sich das Attribut jedoch nicht mehr "physisch" in der übergeordneten Klasse befand, wurde die Fehlermeldung angezeigt, dass das Attribut nicht vorhanden war.
@Eigentum
Ich habe dann über den @propertyDekorateur gelesen . Aber dann habe ich auch gelesen, dass es Probleme für Unterklassen schafft, die tun wollen, self.x = blahwenn xes sich um eine Eigenschaft der übergeordneten Klasse handelt.
Gewünscht
- Lassen Sie den gesamten Client-Code weiterhin verwenden
self.whatever, auch wenn sich diewhateverEigenschaft des übergeordneten Elements nicht "physisch" in der Klasse (oder Instanz) selbst befindet. - Gruppieren Sie verwandte Attribute in diktartigen Containern.
- Reduzieren Sie das extreme Rauschen des Codes in der Hauptklasse.
Zum Beispiel möchte ich das nicht einfach ändern:
larry = 2
curly = 'abcd'
moe = self.doh()
Das mögen:
larry = something_else('larry')
curly = something_else('curly')
moe = yet_another_thing.moe()
… Weil das immer noch laut ist. Obwohl dies ein einfaches Attribut erfolgreich zu etwas macht, das die Daten verwalten kann, hatte das Original 3 Variablen und die optimierte Version hat immer noch 3 Variablen.
Mit so etwas würde ich jedoch gut zurechtkommen:
stooges = Stooges()
Und wenn eine Suche nach self.larryfehlschlägt, prüft etwas, stoogesob larryes vorhanden ist. (Es muss aber auch funktionieren, wenn eine Unterklasse dies larry = 'blah'auf Klassenebene versucht .)
Zusammenfassung
- Möchten Sie verwandte Gruppen von Attributen in einer übergeordneten Klasse durch ein einzelnes Attribut ersetzen, in dem alle Daten an anderer Stelle gespeichert sind
- Möchten Sie mit vorhandenem Client-Code arbeiten, der (z. B.)
larry = 'blah'auf Klassenebene verwendet - Sie möchten weiterhin zulassen, dass Unterklassen diese überarbeiteten Attribute erweitern, überschreiben und ändern, ohne zu wissen, dass sich etwas geändert hat
Ist das möglich? Oder belle ich den falschen Baum an?