2010-09-24 4 views
10

Ich habe eine Klasse geschrieben, deren Implementierung .__hash__() lange dauert. Ich habe darüber nachgedacht, seinen Hash zu cachen und ihn in einer Variablen wie ._hash zu speichern, so dass die .__hash__() Methode einfach ._hash zurückgeben würde. (Was wird entweder am Ende der .__init__() oder das erste Mal .__hash__() genannt wird.)Python: Gibt es einen Grund * nicht * den Hash eines Objekts zu cachen?

Meine Argumentation war: "Dieses Objekt ist unveränderlich -> Sein Hash wird sich nie ändern -> Ich kann den Hash Cache."

Aber jetzt hat mich das denken: Sie können das gleiche über jeder hashable Objekt sagen. (Mit Ausnahme von Objekten, deren Hash ihre ID ist.)

Also gibt es jemals einen Grund nicht den Hash eines Objekts zu cachen, außer für kleine Objekte, deren Hash-Berechnung sehr schnell ist?

Antwort

8

Sicher, es ist in Ordnung, den Hash-Wert zwischenzuspeichern. Tatsächlich macht Python das für Strings selbst. Der Kompromiss besteht zwischen der Geschwindigkeit der Hash-Berechnung und dem Speicherplatz, der zum Speichern des Hash-Werts benötigt wird. Dieser Kompromiss ist zum Beispiel, warum Tupel ihren Hash-Wert nicht zwischenspeichern, sondern Zeichenketten (siehe request for enhancement #1462796).

0

Der übliche Grund ist, dass die meisten Objekte in Python veränderbar sind. Wenn der Hash also von den Eigenschaften abhängt, ändert er sich, sobald Sie eine Eigenschaft ändern. Wenn Ihre Klasse wirklich unveränderlich ist und (alle Eigenschaften, die in den Hash eingegeben werden, auch unveränderlich sind!), Können Sie den Hash zwischenspeichern.

+5

Wenn ein Objekt veränderbar ist, ist es natürlich eine schlechte Idee, "__hash__" überhaupt zu implementieren. Die einzigen eingebauten Verwendungen von '__hash__' erfordern, dass der Hash stabil ist. –

+2

Nein, die Standardimplementierung von '__hash__' gibt nichts anderes zurück, wenn Sie eine Eigenschaft für ein Objekt ändern. Weil das standardmäßig für jedes Objekt gilt: 'hash (obj) == id (obj) == hash (id (obj))' - das bedeutet, dass Objekte ihre ID als Hash nehmen. Die ID ist statisch. Sie können also sagen, dass Objekte ihren Hash standardmäßig "zwischenspeichern". –

Verwandte Themen