Vererbung is doof

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

Hallo,

Ich habe eine Basisklasse Base mit der Basisfunktionalität.
Nun will ich davon Subklassen SubFx haben, die jeweils eine Funktionalität Fx implementieren.
Z.B. SubF1, SubF2, SubF3, ...
Jetzt will ich dass die einzelnen Subklassen auch die jeweils anderen Funktionalitäten haben:
SubF1, SubF1F2, SubF1F2F3 ...
Und danach will ich extensiv in meiner Basisklasse und den Subklassen herumpfuschen ohne andersowo Änderungen machen zu müssen :)

Decorator ist keine gute Lösung, da ich Methoden nach einer bestimmten Reihenfolge überschreiben muss. Man könnte vllt noch einschränken welche Subklassen des Interfaces man im Konstruktor zulässt. Andererseits will ich kleine Klassen haben und wenn ich Decorator verwende wimmelt es von Funktionen, die nicht direkt mit der Aufgabe der Klasse zusammenhängen.

Es wäre toll wenn es eine Klassen vom Typ ExtendableClass mit folgenden Eigenschaften gäbe:
Ich kann eine neue Klasse Plugin schreiben und sie der ExtendableClass hinzufügen.
Dabei werden alle Methoden die mit @add deklariert sind zur ursprünglichen Klasse hinzugefügt.
Alle Methoden die mit @replace markiert sind ersetzen die vorherige Methode in ExtendableClass.
Alle Methoden die mit @chain versehen sind werden in eine Kette mit der vorherigen Methode in ExtendableClass bzw. mit den vorherigen Methoden gehängt und nacheinander ausgeführt. Dabei kann wie beim Decorator auf den Rückgabewert der vorherigen Methode zugegriffen werden.

Von Plugin aus hat man Zugriff auf alle Attribute des ExtendableClass Objektes und allen anderen Plugins die der Klasse hinzugefügt wurden.
Ich habe versucht das ganze dynamisch zu implementieren was einigermaßen hingehauen hat. Ein statischer Ansatz wäre aber vermutlich schöner und man könnte tatsächlich die Klasse erweitern anstatt das Objekt. Dadurch bräuchte man auch keine umständlichen Methoden mehr, die vorher überprüfen ob das Attribut tatsächlich schon in ExtendableClass vorhanden ist. Man könnte auch noch eine Möglichkeit einbauen Abhängigkeiten zu benötigten Plugins aufzulösen.

So könnte man die verschiedenen Methoden sehr einfach statisch zu der Klasse linken.

Entschuldigt bitte die nicht ganz pythonische Ausdrucksweise.

Was denkt ihr dazu?

[Edit] "Funktionen" durch "Methoden" ersetzt
Zuletzt geändert von Boa am Freitag 19. August 2011, 19:51, insgesamt 1-mal geändert.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Ich weiß mal wieder nicht, ob ich das Problem richtig verstehe...

Aber mir scheint, das könnte ein Ansatz sein:

Code: Alles auswählen

>>> def method(self, foo):
...     print self
...     print foo
... 
>>> MyClass = type('AnyClass', (object,), {'method': method})
>>> ac = MyClass()
>>> ac.method('foo')
<__main__.AnyClass object at 0x7f0d4485b950>
foo
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

@mutetella: method ist in deinem Fall eine Funktion und keine Methode
Ich weiß mal wieder nicht, ob ich das Problem richtig verstehe...
Das Problem ist für mich auch nicht ganz trivial zu erklären.

Vereinfacht geht es darum einzelne Klassen wie in einem Spielzeugkasten aus anderen zusammenzubauen.
Genauer gesagt gibt es eine vollständige Klasse die ich ExtendableClass genannt habe und soetwas wie eine Teil Klasse Plugin, die nicht unbedingt eigenständig lauffähig ist. Plugin soll dazu verwendet werden ExtendableClass um bestimmte Methoden zu erweitern.

Z.B. hat man eine Klasse Math vom Typ ExtendableClass und erweitert sie mit Math.add(SinePlugin) um das Plugin SinePlugin, welches die Methoden sin(), cos(), tan() etc. bereitstellt. Es wären noch etliche andere Plugins denkbar, wie CryptoPlugin für cryptographische Funktionen.
Das wäre der einfachste Fall. Nun kann man sich noch EfficientFunctionPlugin hinzudenken, welches beim Hinzufügen die sin() Funktion durch eine zeiteffizientere ersetzt in der die Werte in einer Tabelle bereits vorberechnet sind. Als nächstes noch ein LoggingPlugin, welches die Methoden sin() und tan() definiert und mit den gleichnamigen Methoden in Math verkettet wird, sodass deren Aufruf in eine Datei gelogged werden kann.

Vielleicht ist es durch das aus der Luft gegriffene Beispiel einfacher zu verstehen.

Der Hauptnachteil ist, dass eine Programmiersprache welche dieses Feature unterstützt eben dadurch komplexer ist. Der Vorteil wäre meiner Meinung nach die Code Einsparung und erleichterte Maintainance bei großen Klassenhierarchien.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@Boa:
'type()', das in meinem Beispiel die Klasse 'AnyClass' zurückgibt, verwendet 'method' als Methode von 'AnyClass':

Code: Alles auswählen

>>> ac.method
>>> <bound method AnyClass.method of <__main__.AnyClass object at 0x1793990>>
Ich bleibe dabei: Der Ansatz könnte durchaus eine Lösung sein. Über die Parameter 'name', 'bases' und 'dict' kannst Du aus einem vorhandenen Pool neue Typen/Klassen bilden.


mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten