Betrachten Sie dieses Snippet:
%Vor%was zu:
führt %Vor%Kann jemand erklären, warum das Stichwort 'in' für Mengen und Listen eine andere Bedeutung hat? Ich hätte erwartet, dass beide True zurückgeben, besonders wenn der Typ, der getestet wird, Gleichheitsmethoden definiert hat.
Die Bedeutung ist die gleiche, aber die Implementierung ist anders. Listen prüfen einfach jedes Objekt und prüfen auf Gleichheit, damit es für Ihre Klasse funktioniert. Setzt die Objekte zuerst auf Hashwert, und wenn sie den Hash nicht richtig implementieren, scheint der Satz nicht zu funktionieren.
Ihre Klasse definiert __eq__
, definiert aber nicht __hash__
und funktioniert daher nicht ordnungsgemäß für Sätze oder als Schlüssel von Wörterbüchern. Die Regel für __eq__
und __hash__
besteht darin, dass zwei Objekte, die __eq__
als True haben, ebenfalls gleiche Hashes haben müssen. Standardmäßig basieren Objekte auf ihrer Speicheradresse. Ihre zwei Objekte, die nach Ihrer Definition gleich sind, liefern also nicht den gleichen Hash, also brechen sie die Regel über __eq__
und __hash__
.
Wenn Sie eine __hash__
-Implementierung angeben, funktioniert das problemlos. Für Ihren Beispielcode könnte es sein:
In fast jeder beliebigen Hashtabellen-Implementierung, einschließlich Pythons, müssen Sie die Hashing-Methode überschreiben, wenn Sie die Gleichheitsmethode überschreiben (in Python ist dies __hash__
). Der Operator in
für Listen überprüft nur die Gleichheit mit jedem Element der Liste, wobei der Operator in
zuerst das gesuchte Objekt hasht, nach einem Objekt in diesem Slot der Hashtabelle sucht und dann auf Gleichheit prüft wenn sich etwas im Slot befindet. Wenn Sie also __eq__
außer Kraft setzen, ohne __hash__
zu überschreiben, können Sie nicht garantieren, dass der Operator in
für Sets den richtigen Slot eincheckt.