Seite 1 von 1
Signaturübernahme bei Vererbung?
Verfasst: Freitag 23. April 2010, 10:39
von snafu
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?
Verfasst: Freitag 23. April 2010, 11:11
von helduel
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
Verfasst: Freitag 23. April 2010, 12:16
von Leonidas
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.
Verfasst: Freitag 23. April 2010, 12:38
von helduel
Den wraps-Decorator findet man in den functools. Aber der überschreibt nur __name__, __module__ und __doc__. An den Funktionsargumenten dreht der nichts.
Gruß,
Manuel
Verfasst: Freitag 23. April 2010, 12:44
von Leonidas
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.
Verfasst: Freitag 23. April 2010, 21:49
von snafu
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.
Verfasst: Freitag 23. April 2010, 22:00
von Leonidas
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.
Verfasst: Samstag 24. April 2010, 10:51
von 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.