Función __hash__ y función __eq__ de Python

Las colecciones con hash requieren los elementos de la colección para lograr una __eq__suma __hash__, y estos dos métodos se pueden usar como una vívida analogía:

Un conjunto de hash son muchos cubos, pero solo se puede colocar una bola en cada cubo.

  • __hash__La función de la función es encontrar la ubicación del depósito, cuyo número es el depósito.
  • __eq__La función de la función es que cuando ya hay una bola en el balde, pero viene otra pelota, afirma que también se debe poner en el balde (la __hash__función le dice la posición del balde), y los dos lados están bloqueados, entonces use la __eq__función Para juzgar si las dos bolas son iguales, si se juzga que es igual, entonces la bola no debe colocarse en el balde más tarde, y el conjunto hash mantiene el status quo.
class Foo:
    def __init__(self, item):
        self.item = item

    def __eq__(self, other):
        print('使用了equal函数的对象的id',id(self))
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        else:
            return False
    def __hash__(self):
        print('f'+str(self.item)+'使用了hash函数')
        return hash(self.item)       
f1 = Foo(1)
f2 = Foo(2)
f3 = Foo(3)
fset = set([f1, f2, f3])
print(fset)
print()
f = Foo(3)
fset.add(f)
print('f3的id:',id(f3))
print('f的id:',id(f))

resultado de la operación:

f1使用了hash函数
f2使用了hash函数
f3使用了hash函数
{
    
    <__main__.Foo object at 0x0000023769AB67C0>, <__main__.Foo object at 0x0000023769AC5C10>, <__main__.Foo object at 0x0000023769AC5C40>}

f3使用了hash函数
使用了equal函数的对象的id 2437019360320
f3的id: 2437019360320
f的id: 2437019360368

Se puede ver que cuando se agregan f1, f2 y f3 al conjunto, la __hash__función se llamará cada vez .
Dado que la ___hash__función que definí es return hash (self.item), la posición del depósito encontrada por f y f3 es la misma porque sus elementos son iguales. Al ejecutar fset.add (f), f llamará a su propia __hash__función para encontrar la posición del depósito al que pertenece f. Pero esta vez el cubo tiene otra bola, por lo que debe dedicar este tiempo __eq__a determinar si dos objetos son iguales, puede ver en la salida, ya está sujeto a la llamada __eq__y el objeto posterior a comparar (ver ID de objeto ).
Aquí, si se trata de la operación de eliminación fset.remove (Foo (3)), el principio es el mismo. Primero usa el hash para encontrar la posición del cubo. Si hay una bola en el cubo, juzga si las dos bolas son iguales, y si son iguales, pon la bola en el cubo Tirar a la basura.

Explicación oficial

Cuando se llama a la función hash para el conjunto hash (set, frozenset, dict), debe devolver un valor int. El único requisito es que si se considera que dos objetos son iguales, sus valores hash también deberían ser iguales. Cuando se comparan dos objetos para determinar la igualdad, los miembros del objeto se utilizan para la comparación. Se recomienda poner los miembros en el antepasado original y luego obtener el valor hash del antepasado original para comparar.

Cuando la clase no define __eq__()métodos, tampoco debería definir __hash__()métodos. Si define __eq__()métodos pero no __hash__()métodos, las instancias de esta clase no se pueden usar en colecciones hash. Si una clase define un objeto mutable (esto debería significar que uno de los miembros de la clase es un objeto mutable) e implementa un __eq__()método, entonces esta clase no debería implementar el método hash (), porque la implementación de objetos hash () implementar) requiere que el valor hash de la clave no se modifique (si el valor hash de un objeto cambia, se colocará en el contenedor hash incorrecto)

Hay valores predeterminados __eq__y __hash__métodos en las clases definidas por el usuario ; con él, todas las instancias de objeto son desiguales (a menos que se esté comparando con usted mismo) x == yy son equivalentes a esto cuando las compara hash(x) == hash(y).
Solo lograr __eq__(demostración de error)

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Foo:
    def __init__(self, item):
        self.item = item

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        else:
            return False

f1 = Foo(1)
f2 = Foo(1)
f3 = Foo(1)
print(set([f1, f2, f3]))

Error de ejecución:

Traceback (most recent call last):
  File "c:/Users/Administrator/Desktop/MyFile/MyCoding/Other/hashtest.py", line 14, in <module>
    print(set([f1, f2, f3]))
TypeError: unhashable type: 'Foo'

Supongo que te gusta

Origin blog.csdn.net/sinat_38682860/article/details/109292484
Recomendado
Clasificación