2009-06-30 5 views
24

Blick durch decimal.py, es verwendet NotImplemented in vielen speziellen Methoden. z.B.Python NotImplemented Konstante

class A(object): 
    def __lt__(self, a): 
     return NotImplemented 

    def __add__(self, a): 
     return NotImplemented 

Die Python docs say:

NotImplemented

Spezialwert, der durch den „reichen Vergleich“ spezielle Methoden zurückgegeben werden können (__eq__(), __lt__(), und Freunde), um anzuzeigen, dass der Vergleich nicht mit bezüglich des anderen Typs durchgeführt wird.

Es wird nicht über andere spezielle Methoden gesprochen und beschreibt auch nicht das Verhalten.

Es scheint, ein magisches Objekt zu sein, das, wenn es von anderen speziellen Methoden zurückgegeben wird, TypeError erhöht, und in "reichem Vergleich" macht spezielle Methoden nichts.

z.B.

print A() < A() 

druckt True, aber

print A() + 1 

wirft TypeError, so dass ich bin neugierig, was los ist und was ist die Nutzung/Verhalten von NotImplemented.

+2

Alle korrekt. Sie haben NotImplemented vollständig beschrieben. Was ist die Frage? –

+0

meine Frage war, dass, wenn in doc, speziell erwähnt "Rich Comparison" spezielle Methoden, sollten andere Methoden es ignorieren, schließlich ist es nur ein anderes Objekt, konnte ich nicht doc erklären allgemeines Verhalten oder wie NotImplementiert –

Antwort

26

NotImplemented können Sie angeben, dass ein Vergleich zwischen den beiden angegebenen Operanden nicht implementiert wurde (anstatt anzugeben, dass der Vergleich gültig ist, aber False ergibt, für die zwei Operanden).

Vom Python Language Reference:

Für Objekte x und y, erste x.__op__(y) versucht. Wenn dies nicht implementiert ist oder gibt NotImplemented zurück, wird y.__rop__(x) versucht. Wenn auch nicht implementiert ist oder NotImplemented zurückgegeben wird, wird eine TypeError-Ausnahme ausgelöst. Aber siehe folgende Ausnahme:

Ausnahme zum vorherigen Punkt: Wenn der linke Operand eine Instanz einer eingebauten Typ oder eine neuen Stil-Klasse und der rechten Operanden ist eine Instanz eines richtige Unterklasse von dass Art oder Klasse und überschreibt die __rop__() Methode der Basis, der rechten __rop__() Methode des Operanden wird versucht vor dem linken Operanden __op__() Methode. Dies geschieht, damit eine Unterklasse Binäroperatoren vollständig überschreiben kann.Andernfalls würde der linken Operanden __op__() Methode immer den rechten Operanden annehmen: Wenn ein Instanz einer bestimmten Klasse zu erwarten ist, eine Instanz einer Unterklasse dieser Klasse ist immer akzeptabel.

+3

ok zu finden, so Im allgemeinen Verhalten ist, wenn der Rückgabewert NotImplemented ist, versuchen Sie etwas anderes, wenn das nicht möglich ist. raise TypeError –

+0

Ist es eine schlechte Idee, es in anderen Kontexten zu verwenden, wie zB ein Mapping zwischen verschiedenen Typen? – endolith

4

es tatsächlich die gleiche Bedeutung hat, wenn sie von __add__ wie aus __lt__ zurückgegeben, ist der Unterschied Python 2.x andere Weise versucht, die Objekte zu vergleichen, bevor er aufgibt. Python 3.x löst einen TypeError aus. In der Tat kann Python auch andere Dinge für ausprobieren, siehe __radd__ und (obwohl ich unscharf bin) __coerce__.

# 2.6 
>>> class A(object): 
... def __lt__(self, other): 
...  return NotImplemented 
>>> A() < A() 
True 

# 3.1 
>>> class A(object): 
... def __lt__(self, other): 
...  return NotImplemented 
>>> A() < A() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: A() < A() 

Weitere Informationen finden Sie unter Ordering Comparisions (3.0 docs).

0

Wenn Sie es von __add__ zurückgeben, verhält es sich wie das Objekt hat keine __add__ Methode, und eine TypeError erhöhen.

Wenn Sie NotImplemented aus einer reichen Vergleichsfunktion zurückgeben, verhält sich Python wie die Methode wurde nicht implementiert, das heißt, es wird auf die Verwendung __cmp__ zurückgreifen.