¿Por qué -1 y -2 ambos hash a -2 en CPython? [duplicar]


Posible Duplicado:
¿Cuándo se calcula el hash de un objeto python y por qué es diferente el hash de -1?

¿Por qué -1 y -2 ambos hash al mismo número si Python?

Ya que lo hacen, ¿cómo distingue Python estos dos números?

>>> -1 is -2
False
>>> hash(-1) is hash(-2)
True
>>> hash(-1)
-2
>>> hash(-2)
-2
Author: poke, 2012-04-12

1 answers

-1 es un valor reservado en el nivel C de CPython que evita que las funciones hash puedan producir un valor hash de -1. Como señaló DSM, lo mismo no es cierto en IronPython y PyPy donde hash(-1) != hash(-2).

Ver esta respuesta Quora :

Si escribe un tipo en un módulo de extensión C y proporciona un tp_hash método, usted tiene que evitar -1 - si devuelve -1, Python asumirá querías lanzar un error.

Si escribe una clase en Python puro y proporcionar un método __hash__, no hay tal requisito, afortunadamente. Pero eso es porque el código C que invoca su método __hash__ hace eso por usted-si su __hash__ devuelve -1, luego hash() aplicado a su objeto realmente devolverá -2.

Que realmente solo reempaqueta la información de effbot :

El valor hash -1 está reservado (se usa para marcar errores en la C aplicación). Si el algoritmo hash genera esto valor, simplemente use -2 en su lugar.

También puedes ver esto en la fuente. Por ejemplo, para el objeto int de Python 3, esto se encuentra al final de la implementación hash :

if (x == (Py_uhash_t)-1)
    x = (Py_uhash_t)-2;
return (Py_hash_t)x;

Ya que lo hacen, ¿cómo distingue Python estos dos números?

Dado que todas las funciones hash asignan un espacio de entrada grande a un espacio de entrada más pequeño, siempre se esperan colisiones, sin importar cuán buena sea la función hash. Pensar en cadenas de hashing, para ejemplo. Si los códigos hash son enteros de 32 bits, tiene 2^32 (un poco más de 4 mil millones) códigos hash. Si considera todas las cadenas ASCII de longitud 6, tiene (2^7)^6 (poco menos de 4,4 billones) elementos diferentes en su espacio de entrada. Con solo este conjunto, está garantizado que tendrá muchas, muchas colisiones sin importar lo bueno que sea. Añadir caracteres Unicode y cadenas de longitud ilimitada a eso!

Por lo tanto, el código hash solo sugiere en la ubicación de un objeto, una prueba de igualdad sigue para probar las claves candidatas. Para implementar una prueba de membresía en un conjunto de tablas hash, el código hash le da un número de "cubo" en el que buscar el valor. Sin embargo, todos los elementos establecidos con el mismo código hash están en el cubo. Para esto, también necesita una prueba de igualdad para distinguir entre todos los candidatos en el cubo.

Este código hash y la dualidad de la igualdad se insinúa en la documentación de CPython sobre objetos hashables. En otros idiomas / frameworks, hay una guía / regla que si proporciona una función de código hash personalizada, también debe proporcionar una prueba de igualdad personalizada (realizada en los mismos campos que la función de código hash).


De hecho, la versión de Python de hoy aborda exactamente esto, con un parche de seguridad que aborda el problema de eficiencia cuando esto (valores hash idénticos, pero a escala masiva) se usa como un ataque de denegación de servicio - http://mail.python.org/pipermail/python-list/2012-April/1290792.html

 36
Author: andrew cooke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-09 09:35:56