2017-06-01 8 views
11

Ist es für sich selbst und Ihr Team, die Klasse korrekt zu implementieren? Ich habe nicht vollständig die Verwendung einer abstrakten Klasse wie folgt aus:Wann sollte 'raise NotImplementedError' verwendet werden?

class RectangularRoom(object): 
    def __init__(self, width, height): 
     raise NotImplementedError 

    def cleanTileAtPosition(self, pos): 
     raise NotImplementedError 

    def isTileCleaned(self, m, n): 
     raise NotImplementedError 
+2

Cross-site Betrüger: https://softwareengineering.stackexchange.com/q/231397/110531 – jonrsharpe

+1

Ich würde sagen: Wenn es das ["Prinzip der geringsten Verwunderung" erfüllt (https://en.wikipedia.org/wiki/Prinzip der Leerbesetzung). – MSeifert

Antwort

15

Da die Dokumentation [docs] heißt,

In benutzerdefinierten Basisklassen, abstrakte Methoden sollten diese Ausnahme auslösen, wenn sie benötigen abgeleitete Klassen, um die Methode zu überschreiben, oder während die Klasse entwickelt wird, um anzuzeigen, dass die echte Implementierung noch hinzugefügt werden muss.

Beachten Sie, dass, obwohl die Haupt angegebenen Anwendungsfall dieser Fehler die Angabe der abstrakten Methoden, die auf geerbten Klassen umgesetzt werden sollten, können Sie es trotzdem verwenden können Sie möchten, wie für die Anzeige eines TODO Marker.

+0

Für abstrakte Methoden bevorzuge ich 'abc' (siehe [meine Antwort] (https://stackoverflow.com/a/44316506/4653485)). –

0

Vielleicht möchten Sie verwenden, um die @property Dekorateur,

>>> class Foo(): 
...  @property 
...  def todo(self): 
...    raise NotImplementedError("To be implemented") 
... 
>>> f = Foo() 
>>> f.todo 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in todo 
NotImplementedError: To be implemented 
+0

Ich sehe nicht, wie dies die Frage angeht, welches * wann es zu verwenden ist *. – TemporalWolf

0

Überlegen Sie, ob statt es war:

class RectangularRoom(object): 
    def __init__(self, width, height): 
     pass 

    def cleanTileAtPosition(self, pos): 
     pass 

    def isTileCleaned(self, m, n): 
     pass 

und Sie Unterklasse und vergessen, es zu sagen, wie man isTileCleaned() oder vielleicht wahrscheinlicher , typo es als isTileCLeaned(). Dann erhalten Sie in Ihrem Code eine None, wenn Sie es anrufen.

  • Erhalten Sie die überschriebene Funktion, die Sie wollten? Definitiv nicht.
  • Ist None gültige Ausgabe? Wer weiß.
  • Ist das beabsichtigte Verhalten? Fast sicher nicht.
  • Wird ein Fehler angezeigt? Es kommt darauf an.

Diese Kräfte Sie es implementieren, da es wird eine Ausnahme werfen, bis Sie das tun. Dies entfernt eine Menge stiller Fehler. Es ist ähnlich wie, warum ein bare except is almost never a good idea: weil Leute Fehler machen und das stellt sicher, dass sie nicht unter den Teppich gekehrt werden.

3

Als Uriel says ist es für eine Methode in einer abstrakten Klasse gedacht, die in der Kindklasse implementiert werden soll, aber auch zum Anzeigen eines TODO verwendet werden kann.

Python 3 kommt mit einer Alternative für den ersten Anwendungsfall: Abstract Base Classes. Diejenigen, die Hilfe, die abstrakte Klassen:

class C(abc.ABC): 
    @abstractmethod 
    def my_abstract_method(self, ...): 
    ... 

Wenn C instanziiert wird, erhalten Sie eine Fehlermeldung erhalten, weil my_abstract_method abstrakt ist. Sie müssen es in einer untergeordneten Klasse implementieren.

TypeError: Can't instantiate abstract class C with abstract methods my_abstract_method 

Subclass C und my_abstract_method implementieren.

class D(C): 
    def my_abstract_method(self, ...): 
    ... 

Jetzt können Sie D instanziieren.

C.my_abstract_method muss nicht leer sein. Es kann von unter Verwendung super() aufgerufen werden.

Ein Vorteil gegenüber NotImplementedError ist, dass Sie eine explizite Exception zur Instanziierungszeit erhalten, nicht zur Zeit des Methodenaufrufs.

+1

Auch verfügbar in Python 2.6+. Einfach 'von abc import ABCMeta, abstractmethod' und definiere dein ABC mit' __metaclass__ = ABCMeta'. Dokumente: https://docs.python.org/2/library/abc.html – BoltzmannBrain

Verwandte Themen