In Java bietet die @Override
Annotation beispielsweise nicht nur eine Überprüfung einer Überschreibung zur Kompilierungszeit, sondern sorgt auch für einen hervorragenden selbstdokumentierenden Code.
Ich suche nur nach Dokumentation (obwohl es ein Bonus ist, wenn es ein Indikator für einen Prüfer wie Pylint ist). Ich kann irgendwo einen Kommentar oder eine Dokumentzeichenfolge hinzufügen, aber wie kann eine Überschreibung in Python idiomatisch angezeigt werden?
Antworten:
Basierend auf dieser und der Antwort von fwc: s habe ich ein installierbares Pip-Paket https://github.com/mkorpela/overrides erstellt
Von Zeit zu Zeit schaue ich mir diese Frage an. Dies geschieht hauptsächlich, nachdem (erneut) derselbe Fehler in unserer Codebasis aufgetreten ist: Jemand hat beim Umbenennen einer Methode in der "Schnittstelle" eine Implementierungsklasse "interface" vergessen.
Nun, Python ist nicht Java, aber Python hat Macht - und explizit ist besser als implizit - und es gibt echte konkrete Fälle in der realen Welt, in denen mir dieses Ding geholfen hätte.
Hier ist eine Skizze des Overrides-Dekorateurs. Dadurch wird überprüft, ob die als Parameter angegebene Klasse denselben Methodennamen (oder einen anderen Namen) wie die zu dekorierende Methode hat.
Wenn Sie sich eine bessere Lösung vorstellen können, posten Sie diese bitte hier!
Es funktioniert wie folgt:
und wenn Sie eine fehlerhafte Version ausführen, wird beim Laden der Klasse ein Assertionsfehler ausgelöst:
quelle
overrides
könnte die Dokumentzeichenfolge der überschriebenen Methode kopieren, wenn die überschreibende Methode keine eigene hat.Hier ist eine Implementierung, für die keine Angabe des Namens der Schnittstellenklasse erforderlich ist.
quelle
Wenn Sie dies nur zu Dokumentationszwecken wünschen, können Sie Ihren eigenen Override-Dekorator definieren:
Dies ist wirklich nichts anderes als eine Augenweide, es sei denn, Sie erstellen Override (f) so, dass tatsächlich nach einem Override gesucht wird.
Aber das ist Python. Warum sollte man es so schreiben, als wäre es Java?
quelle
override
Dekorateur eine tatsächliche Validierung durch Inspektion hinzufügen .Python ist kein Java. Es gibt natürlich keine Überprüfung der Kompilierungszeit.
Ich denke, ein Kommentar in der Dokumentationszeichenfolge ist ausreichend. Auf diese Weise kann jeder Benutzer Ihrer Methode eingeben
help(obj.method)
und feststellen, dass es sich bei der Methode um eine Überschreibung handelt.Sie können auch eine Schnittstelle explizit erweitern, mit
class Foo(Interface)
der Benutzer tippen könnenhelp(Interface.method)
, um sich ein Bild von der Funktionalität zu machen, die Ihre Methode bereitstellen soll.quelle
@Override
Java besteht nicht darin, zu dokumentieren, sondern einen Fehler zu erkennen, wenn Sie beabsichtigten, eine Methode zu überschreiben, aber am Ende eine neue zu definieren (z. B. weil Sie einen Namen falsch geschrieben haben; in Java kann dies auch passieren, weil Sie ihn verwendet haben die falsche Signatur, aber dies ist kein Problem in Python - aber Rechtschreibfehler sind immer noch).@Override
ist neben der Überprüfung der Kompilierungszeit auch die Dokumentation.Improvisieren auf @mkorpela tolle Antwort , hier ist eine Version mit
genauere Überprüfungen, Benennungen und ausgelöste Fehlerobjekte
So sieht es in der Praxis aus:
NotImplementedError
" nicht in Basisklasse implementiert "führt zu einem aussagekräftigeren
NotImplementedError
Fehlervoller Stapel
NotImplementedError
" erwarteter implementierter Typ "führt zu einem aussagekräftigeren
NotImplementedError
Fehlervoller Stapel
Das Tolle an der Antwort von @mkorpela ist, dass die Überprüfung während einer Initialisierungsphase erfolgt. Die Prüfung muss nicht "ausgeführt" werden. In Bezug auf die vorherigen Beispiele
class B
wird nie initialisiert (B()
), aber derNotImplementedError
Wille wird immer noch ausgelöst. Dies bedeutet, dassoverrides
Fehler früher erkannt werden.quelle
overrides.py
. Ich bin mir nicht sicher, was ich sonst noch erheblich verbessern kann, außer die Ausnahmetypen vonTypeError
auf zu ändernNotImplementedError
.types.MethodType
. Das war eine gute Idee in Ihrer Antwort.Wie andere bereits gesagt haben, gibt es im Gegensatz zu Java kein @ Overde-Tag. Oben können Sie jedoch mithilfe von Dekoratoren ein eigenes Tag erstellen. Ich würde jedoch empfehlen, die globale Methode getattrib () anstelle des internen Diktats zu verwenden, damit Sie Folgendes erhalten:
Wenn Sie möchten, können Sie getattr () in Ihrem eigenen Versuch abfangen. Catch löst Ihren eigenen Fehler aus, aber ich denke, die Methode getattr ist in diesem Fall besser.
Außerdem werden alle an eine Klasse gebundenen Elemente erfasst, einschließlich Klassenmethoden und Vairables
quelle
Basierend auf der großartigen Antwort von @ mkorpela habe ich ein ähnliches Paket ( ipromise pypi github ) geschrieben, das viele weitere Überprüfungen durchführt:
Angenommen ,
A
erbt vonB
undC
,B
erbt vonC
.Das Modul ipromise überprüft Folgendes :
Wenn
A.f
überschreibtB.f
,B.f
muss vorhanden sein und vonA
erbenB
. (Dies ist die Prüfung aus dem Overrides-Paket).Sie haben nicht das Muster
A.f
deklariert, dass es überschreibtB.f
, was dann deklariert, dass es überschreibtC.f
.A
sollte sagen, dass es überschreibt vonC.f
daB
könnte entscheiden, diese Methode nicht mehr zu überschreiben, und das sollte nicht zu nachgelagerten Updates führen.Das Muster
A.f
deklariert nicht, dass es überschrieben wirdC.f
,B.f
deklariert jedoch nicht, dass es überschrieben wird .Sie haben nicht das Muster
A.f
deklariert, dass es überschreibtC.f
, aberB.f
deklariert, dass es von einigen überschreibtD.f
.Es verfügt auch über verschiedene Funktionen zum Markieren und Überprüfen der Implementierung einer abstrakten Methode.
quelle
Hören ist am einfachsten und funktioniert unter Jython mit Java-Klassen:
quelle
Der Dekorateur, den ich erstellt habe, hat nicht nur überprüft, ob der Name des überschreibenden Attributs in einer Oberklasse der Klasse ist, in der sich das Attribut befindet, ohne dass eine Oberklasse angegeben werden muss, sondern auch, ob das überschreibende Attribut vom selben Typ wie das überschriebene sein muss Attribut. Klassenmethoden werden wie Methoden behandelt und statische Methoden werden wie Funktionen behandelt. Dieser Dekorator arbeitet für Callables, Klassenmethoden, statische Methoden und Eigenschaften.
Quellcode finden Sie unter: https://github.com/fireuser909/override
Dieser Dekorator funktioniert nur für Klassen, die Instanzen von override.OverridesMeta sind. Wenn Ihre Klasse jedoch eine Instanz einer benutzerdefinierten Metaklasse ist, verwenden Sie die Funktion create_custom_overrides_meta, um eine Metaklasse zu erstellen, die mit dem Überschreibungsdekorator kompatibel ist. Führen Sie für Tests das Modul override .__ init__ aus.
quelle
In Python 2.6+ und Python 3.2+ können Sie dies tun ( simulieren Sie es tatsächlich , Python unterstützt keine Funktionsüberladung und die untergeordnete Klasse überschreibt automatisch die Methode der Eltern). Wir können hierfür Dekorateure verwenden. Beachten Sie jedoch zunächst, dass Pythons
@decorators
und Java@Annotations
völlig unterschiedliche Dinge sind. Der vorherige ist ein Wrapper mit konkretem Code, während der spätere ein Flag für den Compiler ist.Dazu zuerst
pip install multipledispatch
Ausgabe:
Eine Sache, an die Sie sich erinnern sollten, ist, dass Python keine direkte Funktionsüberladung hat. Selbst wenn Klasse B nicht von Klasse A erbt, sondern alle diese
foo
benötigt, müssen Sie auch @Override verwenden (obwohl der Alias 'Überladung' aussehen wird besser in diesem Fall)quelle