Es fácil ver que la opción # 3 es válida para los objetos definidos por el usuario. Esto permite que el hash varíe si muta el objeto, pero si alguna vez usa el objeto como una clave de diccionario, debe asegurarse de evitar que el hash cambie.
>>> class C:
def __hash__(self):
print("__hash__ called")
return id(self)
>>> inst = C()
>>> hash(inst)
__hash__ called
43795408
>>> hash(inst)
__hash__ called
43795408
>>> d = { inst: 42 }
__hash__ called
>>> d[inst]
__hash__ called
cadenas utilizan la opción # 2: calculan el valor hash de una vez en caché el resultado. Esto es seguro porque las cadenas son inmutables, por lo que el hash nunca puede cambiar, pero si subclase str
el resultado puede no ser inmutable, se volverá a llamar al método __hash__
. Suele pensarse que las tuplas son inmutables, por lo que podría pensar que el hash podría almacenarse en caché, pero de hecho el hash de una tupla depende del hash de su contenido y eso podría incluir valores variables.
Para @max que no cree que las subclases de str
puede modificar el hash:
>>> class C(str):
def __init__(self, s):
self._n = 1
def __hash__(self):
return str.__hash__(self) + self._n
>>> x = C('hello')
>>> hash(x)
-717693723
>>> x._n = 2
>>> hash(x)
-717693722
3 está fuera como he [leer] (http://www.laurentluce.com/posts/ python-dictionary-implementation /) se almacena en caché la primera vez que se llama.Asumiría que la segunda opción es correcta, pero como no estoy seguro, no la publicaré como respuesta :) – rplnt
@rplnt: wrong; eso es simplemente cuando se habla de un diccionario. Su hash se almacenará en el diccionario, pero eso no es cierto para hash general. –
@ChrisMorgan En realidad, no creo que python 'dict' almacene valores hash para sus claves. Por supuesto, las clases individuales pueden hacer lo que quieran en su función '__hash__', por lo que el artículo mencionado anteriormente dice que' str' almacena en caché sus valores hash. – max