[Python Advanced] Clase personalizada: Comparación

4.10.3 Comparación

En Python, a menudo comparamos la igualdad de dos estructuras de datos o comparamos tamaños. Para las estructuras de datos integradas de Python, la comparación de estas estructuras de datos está bien definida.
Las estructuras de datos escritas por los propios usuarios a veces necesitan compararse entre sí. La implementación lógica de la comparación se realiza a través de métodos mágicos.
En Python, si no se escribe una lógica de comparación en la clase personalizada, se usa para la comparación de forma predeterminada.

from icecream import ic


class Date:
    def __init__(self, year, month, date):
        self.year = year
        self.month = month
        self.date = date


x = Date(2022, 2, 22)
y = Date(2022, 2, 22)
ic(x == y)  # 相当于:ic(x is y)

16:34:19|> x == y: Falso

4.10.3.1 eqne

"==" llamará a este método al juzgar si dos objetos son iguales.

from icecream import ic


class Date:
    def __init__(self, year, month, date):
        self.year = year
        self.month = month
        self.date = date

    def __eq__(self, other):
        return self.year == other.year and self.month == other.month and self.date == other.date


x = Date(2022, 2, 22)
y = Date(2022, 2, 22)
ic(x == y)

16:39:20|> x == y: Verdadero

Si Python encuentra que no hay un método no igual definido en la clase autoconstruida, invertirá el método igual como el valor de retorno de no igual.

from icecream import ic


class Date:
    def __init__(self, year, month, date):
        self.year = year
        self.month = month
        self.date = date

    def __eq__(self, other):
        print('__eq__')
        return self.year == other.year and self.month == other.month and self.date == other.date


x = Date(2022, 2, 22)
y = Date(2022, 11, 22)
ic(x != y)

ecuación
16:50:37|> x != y: Verdadero

Si se define el método no igual, solo se llamará al método no igual cuando se considere que no es igual a.

from icecream import ic


class Date:
    def __init__(self, year, month, date):
        self.year = year
        self.month = month
        self.date = date

    def __eq__(self, other):
        print('__eq__')
        return self.year == other.year and self.month == other.month and self.date == other.date

    def __ne__(self, other):
        print('__ne__')
        return self.year != other.year or self.month != other.month or self.date != other.date


x = Date(2022, 2, 22)
y = Date(2022, 11, 22)
ic(x != y)

ne
16:53:01|> x != y: Verdadero

En general, solo necesitamos definir un método __eq__ en la clase autoconstruida.
En los métodos __eq__ y __ne__, es necesario proporcionar otro objeto para comparar: otro, porque estos dos métodos se utilizan para la comparación binaria.
Pero cuando juzgamos si x es igual a y: x == y, en realidad estamos juzgando: x.eq ( y). y se pasará como otro al método __eq__ de x.

4.10.3.2 gt , lt

Igual a, no igual a tener una implementación predeterminada, si no se define, el valor predeterminado se juzgará por sí. Sin embargo, si mayor que y menor que no están definidos, la comparación directa informará un error.

from icecream import ic


class Date:
    def __init__(self, year, month, date):
        self.year = year
        self.month = month
        self.date = date

    def __eq__(self, other):
        print('__eq__')
        return self.year == other.year and self.month == other.month and self.date == other.date

    def __ne__(self, other):
        print('__ne__')
        return self.year != other.year or self.month != other.month or self.date != other.date

    def __gt__(self, other):
        if self.year > other.year:
            return True
        if self.year == other.year:
            if self.month > other.month:
                return True
            if self.month == other.month:
                return self.date > other.date


x = Date(2023, 2, 22)
y = Date(2022, 11, 22)
ic(x > y)

17:08:33|> x > y: Verdadero

Aunque aquí solo definimos el método mayor que, podemos usar directamente el signo menor que en este momento, porque Python tiene por defecto que el signo mayor que y el signo menor que son un par. Cuando no se especifica lo contrario, x > y significa y < x. Si se juzga que x < y, si no hay menos que método en x, encontrará el mayor que método en y, de modo que también se pueda hacer el juicio.

4.10.3.3 siy

Python no especula sobre menor o igual que, mayor o igual que, es decir, mayor o igual que un todo, no mayor o igual que. Cuando mayor o igual no está definido, se informará un error si usa directamente mayor o igual para juzgar, en lugar de llamar a mayor o igual y luego realizar una operación lógica o.

from icecream import ic


class Date:
    def __init__(self, year, month, date):
        self.year = year
        self.month = month
        self.date = date

    def __ge__(self, other):
        print('__ge__')
        if self.year > other.year:
            return True
        if self.year == other.year:
            if self.month > other.month:
                return True
            if self.month == other.month:
                return self.date >= other.date
    def __le__(self, other):
        print('__le__')
        if self.year < other.year:
            return True
        if self.year == other.year:
            if self.month < other.month:
                return True
            if self.month == other.month:
                return self.date <= other.date


x = Date(2023, 2, 22)
y = Date(2022, 11, 22)
ic(x >= y)

ge
17:16:13|> x >= y: Verdadero

4.10.3.4 hash

En Python, cada clase personalizada tendrá un método __hash__ para enlazar de forma predeterminada. Si se define el método __eq__, se eliminará el método __hash__ predeterminado. Esta clase personalizada se volverá imposible de modificar.
La razón es que, en Python, si dos objetos son iguales, entonces los valores hash de esos dos objetos también deben ser iguales. Por lo tanto, debemos definir el método __hash__ nosotros mismos después de definir el método __eq__.
Los requisitos del método __hash__ son:
1. Debe devolver un número entero
2. Para dos objetos iguales, el valor hash también debe ser el mismo.
Lo mejor es usar la función hash que viene con Python para la evaluación, de la siguiente manera:

from icecream import ic


class Date:
    def __init__(self, year, month, date):
        self.year = year
        self.month = month
        self.date = date

    def __eq__(self, other):
        return self.year == other.year and self.month == other.month and self.date == other.date

    def __hash__(self):
        return hash((self.year, self.month, self.date))


x = Date(2023, 2, 22)
y = Date(2023, 2, 22)
dct = {
    
    x: 999, y: 999}
ic(dct)

17:27:37|> dct: {< objeto principal .Date en 0x000001A6C49EBEE0>: 999}

4.10.3.5 booleano

Para todos nuestros objetos personalizados, si se usan directamente como condición de juicio de la instrucción if, devolverán True. Si desea cambiar el resultado de un objeto personalizado al realizar operaciones booleanas, puede utilizar el método mágico __bool__.

from icecream import ic


class Date:
    def __init__(self, year, month, date):
        self.year = year
        self.month = month
        self.date = date

    def __bool__(self):
        print('bool')
        return False



x = Date(2023, 2, 22)
ic(bool(x))
if not x:
    ic(x)

bool
bool
ic| bool(x): Falso
ic| x: < objeto principal .Date en 0x0000026ECCC633A0>

Supongo que te gusta

Origin blog.csdn.net/crleep/article/details/132141606
Recomendado
Clasificación