Benutzerdefinierte Klassenreihenfolge: Kein Fehler ausgelöst, wofür testet Python?

8

Ohne Angabe der Gleichheitsvergleichseigenschaften von Objekten tut Python noch etwas, wenn er > und < verwendet. Worin vergleicht Python diese Objekte, wenn Sie nicht __gt__ oder __lt__ angeben? Ich würde hier einen nicht unterstützten Operandenfehler erwarten, wie Sie beim Versuch, zwei Objekte zusammenzufügen, ohne __add__ zu definieren.

%Vor%     
reptilicus 19.11.2012, 15:24
quelle

3 Antworten

6

Für Objekte wird eine beliebige Reihenfolge festgelegt. Die Reihenfolge ist nur definiert als stable innerhalb einer Programmausführung .

Das bedeutet, es liegt an der Python-Implementierung, beim Vergleich beliebiger Objekte eine Reihenfolge zu definieren. CPython verwendet die Speicheradresse, wenn die Typen identisch sind (aus der C-Quelle ) ):

%Vor%

Derselbe Wert ist die Basis für die id() -Funktion und wird auch in der Standard-Zeichenfolge repr() für benutzerdefinierte Klassen dargestellt, sodass erscheinen kann , die repr() der Klassen bestimmen Bestellung. Es ist nur die Speicheradresse, die das tut.

Für Objekte, die nicht sind, wird stattdessen der Typ Name verwendet (mit numberähnlichen Typen, die vor anderen sortiert werden), und wenn sich die Typen unterscheiden Namen sind gleich, der Code fällt auf die Speicheradresse des Typs zurück (im Gegensatz zur Speicheradresse der Instanz, wenn die Typen identisch sind).

Diese implizite Reihenfolge wurde als Fehler in der Sprache betrachtet und wurde in Python 3 behoben :

  

Die Sortieroperatoren ( < , <= , >= , > ) lösen eine TypeError Ausnahme aus, wenn die Operanden keine sinnvolle natürliche Reihenfolge haben.

Dies gilt für benutzerdefinierte Klassen, die nicht die erforderlichen Bestellhaken : %Vor%     

Martijn Pieters 19.11.2012, 15:51
quelle
4

EDIT: Sehen Sie das Update nach dem Lesen! Die vollkommen richtige Antwort ist "undefined, aber konsistent".

Es testet repr(me) vs repr(you) , das im Wesentlichen String-Vergleich macht. Hier ist ein einfaches Beispiel:

%Vor%

Ich stimme zu, dass mir das etwas seltsam vorkommt. Vielleicht gibt es einen guten Grund dafür, von dem ich nichts weiß?

AKTUALISIEREN : Ich bin falsch bei repr , obwohl es aussieht, als ob es die Basis object repr im Test verwendet. Ссылка

Dort gibt es eine Zeile, die besagt "Die Wahl, ob ein Objekt als kleiner oder größer als ein anderes Objekt betrachtet wird, wird willkürlich, aber konsistent innerhalb einer Ausführung eines Programms gemacht." Mit anderen Worten, es könnte repr verwenden, aber das ist nicht garantiert. Es wird jedoch konsequent durchgeführt werden.

    
dave mankoff 19.11.2012 15:31
quelle
0

Python verwendet die repr() des Objekts, wenn es keine reichen Vergleichsoperatoren gibt. (Zumindest gilt das für Py2; ich weiß nicht für Py3).

Also, wenn du es tust

%Vor%

Die Objekte werden nach ihrer repr() , der A() zuerst und dann nach der B() sortiert.

    
glglgl 19.11.2012 15:31
quelle