Signaturübernahme bei Vererbung?

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
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Der übliche Weg um die Argumente für die __init__-Funktion einer Superklasse durch eine Unterklasse zu übergeben ist ja in etwa so:

Code: Alles auswählen

In [1]: class Foo(object):
   ...:     def __init__(self, foo='bar', ham='spam'):
   ...:         self.foo = foo
   ...:         self.ham = ham
   ...:         
   ...:         

In [2]: class Bar(Foo):
   ...:     def __init__(self, baz=True, **kwargs):
   ...:         Foo.__init__(self, **kwargs)
   ...:         self.baz = baz
   ...:         
   ...:         

In [3]: Bar?
Type:		type
Base Class:	<type 'type'>
String Form:	<class '__main__.Bar'>
Namespace:	Interactive
File:		/usr/lib/pymodules/python2.6/IPython/FakeModule.py
Docstring:
    <no docstring>

Constructor information:
Definition:	Bar(self, baz=True, **kwargs)
...oder man schreibt eben die Argumente für Foo auch nochmal in Bar rein. Meine Frage ist nun: Gibt es eine Möglichkeit, die Signaturen zu kombinieren, so dass mir zB IPython auch foo und ham in der Signatur für Bar anzeigt? Sowas geht nicht, oder?
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

die __init__ von Bar hat nichts mit der __init__ von Foo zu tun. Ein Automatismus zur Übername der Attribute gibt es so nicht. Du könntest aber als Workaround den Docstring von Foo mit in den von Bar kopieren.

Ansonsten: "Explicit is better than implicit". Gib die Argumente in Bar mit an. Dann ist es für jeden offensichtlich, was erwartet oder akzeptiert wird.

Gruß,
Manuel
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich glaube eines der Module ``decorator`` oder ``DecoratorTools`` hatte nen Trick, wie man die Signatur kopiert (die brauchten das, damit die dekorierende Funktion die selbe Signatur hat, wie die dekorierte Funktion). Da kannst du mal nachschauen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Den wraps-Decorator findet man in den functools. Aber der überschreibt nur __name__, __module__ und __doc__. An den Funktionsargumenten dreht der nichts.

Gruß,
Manuel
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

helduel hat geschrieben:Den wraps-Decorator findet man in den functools. Aber der überschreibt nur __name__, __module__ und __doc__. An den Funktionsargumenten dreht der nichts.
Und genau den meinte ich nicht und habe daher auf das ``decorator``-Modul verwiesen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

helduel hat geschrieben:Ansonsten: "Explicit is better than implicit". Gib die Argumente in Bar mit an. Dann ist es für jeden offensichtlich, was erwartet oder akzeptiert wird.
Schon, aber wenn man ein Modul baut, dessen Design sehr stark auf Vererbung setzt, sieht es wegen der Redundanz halt etwas blöd aus. Das Wiederholen von Docstrings endet ja letztlich auch damit, dass man jedes Mal den "Übernehm-Befehl" reinschreiben muss.

@Leonidas: Ich weiß ehrlich gesagt nicht, was du mit dem `decorator`-Modul meinst. Unter diesem oder einem ähnlichem Namen finde ich nichts in der Stdlib. Was man wahrscheinlich machen könnte, wäre ein Dekorator, der die `__init__`-Methode der Superklasse einer dekorierten Methode ausführt und irgendwie auch die Argumente der Superklasse in die Signatur kopiert. Wobei ich mir beim letzten Punkt nicht sicher bin, was die Umsetzbarkeit angeht. Den setzt man halt in den entsprechenden Klassen als `@borrows` oder `@inherits` an `__init__` dran. Naja, vielleicht probier ich mich morgen mal an der Implementierung.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

snafu hat geschrieben:@Leonidas: Ich weiß ehrlich gesagt nicht, was du mit dem `decorator`-Modul meinst.
Das decorator-Modul.

Ich frage mich, ob es ebenfalls so verwirrend gewesen wäre wenn ich lxml statt decorator gesagt hätte. Schließlich habe ich an keiner Stelle behauptet, das decorator-Modul sei Teil der Stdlib sondern einen Blick in dessen Quelltext empfohlen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

@snafu: Mein Gott, die Redundanz bei drei Parametern wird Dich schon nicht umbringen. Vermeiden lässt sich das nun mal nicht, wenn Du auf **kwargs oder Code-Generierung (so geht generator vor) verzichten möchtest, denn aus guten Gründen kann man die Signatur einer Methode nachträglich nicht manipulieren.

Und wenn Du mehr als drei Parameter hast, ist das eher ein Zeichen dafür, dass das Design eben doch nicht so gut auf Vererbung ausgelegt ist.
Antworten