Ist es üblich, einen NotImplementedError für Methoden auszulösen, deren Implementierung noch aussteht, die jedoch nicht abstrakt sein sollen?

34

Ich möchte eine NotImplementedErrorfür jede Methode, die ich implementieren möchte, aber wo ich noch nicht dazu gekommen bin, erhöhen . Möglicherweise habe ich bereits eine teilweise Implementierung, stelle sie jedoch voran, raise NotImplementedError()da sie mir noch nicht gefällt. Auf der anderen Seite halte ich mich auch gerne an Konventionen, weil dies anderen Leuten die Pflege meines Codes erleichtert und Konventionen aus gutem Grund existieren können.

In der Pythons-Dokumentation für NotImplementedError heißt es jedoch:

Diese Ausnahme wird von RuntimeError abgeleitet. In benutzerdefinierten Basisklassen sollten abstrakte Methoden diese Ausnahme auslösen, wenn abgeleitete Klassen zum Überschreiben der Methode erforderlich sind.

Das ist ein viel spezifischerer formaler Anwendungsfall als der, den ich beschreibe. Ist es ein guter, konventioneller Stil, ein zu erheben, NotImplementedErrorum anzuzeigen, dass dieser Teil der API in Arbeit ist? Wenn nicht, gibt es eine andere standardisierte Möglichkeit, dies anzuzeigen?

Gerrit
quelle
Was meinst du mit "angemessen"?
Robert Harvey
1
@RobertHarvey Ich denke, ich meine konventionelle, nach allgemeiner Verwendung. Ich habe meine Frage jetzt umformuliert.
Gerrit
1
Wir verwenden hier hauptsächlich C #, aber diese Art des Ausnahmewerfens ist hier idiomatisch, und ich würde anderswo erwarten. Früh brechen und laut brechen ist eine gute Richtlinie, um potenzielle Probleme schnell zu erkennen (zu lesen: kostengünstig).
Telastyn
Wenn ich eine Klasse erstelle, füge ich TODO-Kommentare in nicht implementierte Methoden ein, bis ich mit der Implementierung der Funktionalität fertig bin. Wenn die Klasse vorher für die Produktion freigegeben würde, würde ich Ausnahmen in Betracht ziehen.
5
Wenn Sie die IDE zum "Implementieren einer Schnittstelle" verwenden, ist dies für Microsoft Visual Studio die Standardeinstellung. Bei Robert Harvey sagt, das Ergebnis ist gut verstanden.
Katzenfutter

Antworten:

34

Es ist erwähnenswert, dass die Python-Dokumentation zwar einen Anwendungsfall (und wahrscheinlich den kanonischen) für diese Ausnahme enthält, ihre Verwendung in anderen Szenarien jedoch nicht ausdrücklich ausschließt.

Ich würde es für angemessen halten, eine NotImplementedError-Ausnahme auszulösen, wenn Sie eine Methode in einer Basisklasse noch nicht überschrieben haben (um die "Schnittstelle" zu erfüllen).

Eine flüchtige Überprüfung bei Google legt nahe, dass die Nutzer verstehen, was Sie meinen, wenn Sie die Ausnahme auf diese Weise verwenden. Es gibt keine Nebenwirkungen oder unbeabsichtigten Konsequenzen, von denen ich weiß; Die Methode löst einfach eine Ausnahme aus, wenn sie aufgerufen wird, und löst eine Ausnahme aus, die von allen gut verstanden wird.


Die Dokumentation für Python 3 spiegelt genau diese Verwendung wider:

In benutzerdefinierten Basisklassen sollten abstrakte Methoden diese Ausnahme auslösen, wenn abgeleitete Klassen zum Überschreiben der Methode erforderlich sind oder wenn die Klasse entwickelt wird, um anzuzeigen, dass die eigentliche Implementierung noch hinzugefügt werden muss . [Betonung hinzugefügt]

Robert Harvey
quelle
+1, aber ich möchte auch hinzufügen, dass für diese Art von Konvention eine kleine Dokumentation einen langen Weg zurücklegen kann. Wie eine einzeilige Notiz in einem Entwickler-Wiki, einer Repo-Readme-Datei oder einer Stilrichtlinie, in der erläutert wird, wofür Sie diese Ausnahme verwenden.
Ben Lee
8

Dies wird verstanden, ob Sie dies tun oder nicht, sollte von lokalen Konventionen (Team- oder Firmenkonventionen) abhängen. Beachten Sie, dass dies im Zusammenhang mit TDD weniger sinnvoll ist, da der TEST bestimmen sollte, dass die Methode nicht implementiert ist.

Die Kurzversion lautet: Verwenden Sie, wenn Sie und Ihr Team dies für angemessen halten.

jmoreno
quelle
5
FWIW, Das Auslösen der Ausnahme sollte ein guter Weg sein, um den Test zum Scheitern zu bringen, wenn Sie aus irgendeinem Grund dieses Verhalten erzwingen müssen. (Dies ist beispielsweise im Rahmen eines Intellisense-Stubs zur Methodendefinition hilfreich.)
DougM
1

Es scheint, dass NotImplementedErrorin der Regel für Python-Feature-Entwicklungen selbst ausgelöst wird, wie die folgenden:

@classmethod
def fromkeys(cls, iterable, v=None):
    # There is no equivalent method for counters because setting v=1
    # means that no element can have a count greater than one.
    raise NotImplementedError(
        'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')

Dokumentation

fromkeys (iterabel)

Diese Klassenmethode ist für Counter-Objekte nicht implementiert.

Quelle

Collections.Counter.fromkeys

Emma
quelle