Curiosidad sobre __hash__()
Chema Cortes
py en ch3m4.org
Vie Feb 6 03:13:15 CET 2009
El Thursday 05 February 2009 14:07:20 Francesc Alted escribió:
> A ver, si a y b *son* el mismo objeto ((2,), que no necesariamente es la
> misma dirección de memoria), la hash ha de ser la misma, no?
Umm! Parece que nos estamos liando más de la cuenta.
Se dice que un objeto es "hashable" si:
a) tiene un valor hash que no cambia en toda su vida (método __hash__)
b) se pueden comparar con otros objetos (métodos __eq__ ó __cmp__), de modo
que si dos objetos tienen el mismo valor, habrán de tener el mismo hash
(aunque sean de distintos tipos).
Si el hash de un objeto no cumple estas dos reglas, entonces no será válido
para, por ejemplo, ser índice de diccionarios o de conjuntos.
Si dos tuplas tienen el mismo "valor" --como en el caso de (2,)-- entonces
deberán tener el mismo hash. Los objetos mutables (listas y diccionarios) no
son hashables. Los objetos definidos por el usuario, al derivar de la
clase 'object' adquieren los métodos __hash__ y __cmp__. El primero da la
dirección de memoria (id()); el segundo siempre da como resultado de la
comparación como distinto.
Pero, como ocurre siempre, se pueden hacer algunas trampas :P
#diccionario con hash "subrogado"
class D(dict):
ID=0
def __init__(self,**kw):
dict.__init__(self,**kw)
self.ID=D.ID
D.ID+=1
def __hash__(self):
return hash(self.ID)
d1=D(a=1,b=2)
print d1,hash(d1)
d2=D(x=123,y=1234)
print d2,hash(d2)
h={d1:"Hola", d2:"Mundo"}
print h
PD Py3k warning: en python3 los objetos definidos por el usuario ya no
adquieren el método __hash__ por defecto. Se supone que basta con tener los
métodos __eq__ ó __cmp__ para poder ser índices de diccionarios.
PD2: desconozco porqué el hash de un objeto definido por el usuario no
coincide con el valor que devuelve la función id(). En toda la documentación
que he consultado dice que debería ser lo mismo. Supongo que habría que
estudiar el código.
------------ próxima parte ------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
URL: <http://mail.python.org/pipermail/python-es/attachments/20090206/fe9a8b31/attachment.pgp>
------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Más información sobre la lista de distribución Python-es