Métodos mágicos básicos

PythonPythonIntermediate
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este tutorial, exploraremos los métodos mágicos básicos en Python. Los métodos mágicos, también conocidos como "dunder" métodos (métodos con doble subrayado), te permiten definir cómo se comportan los objetos de Python en ciertas situaciones, lo que posibilita la manipulación avanzada y personalizada de objetos.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/ObjectOrientedProgrammingGroup(["Object-Oriented Programming"]) python/FunctionsGroup -.-> python/function_definition("Function Definition") python/ObjectOrientedProgrammingGroup -.-> python/classes_objects("Classes and Objects") python/ObjectOrientedProgrammingGroup -.-> python/constructor("Constructor") python/ObjectOrientedProgrammingGroup -.-> python/polymorphism("Polymorphism") python/ObjectOrientedProgrammingGroup -.-> python/encapsulation("Encapsulation") subgraph Lab Skills python/function_definition -.-> lab-7836{{"Métodos mágicos básicos"}} python/classes_objects -.-> lab-7836{{"Métodos mágicos básicos"}} python/constructor -.-> lab-7836{{"Métodos mágicos básicos"}} python/polymorphism -.-> lab-7836{{"Métodos mágicos básicos"}} python/encapsulation -.-> lab-7836{{"Métodos mágicos básicos"}} end

Inicialización y representación de objetos

En esta sección, exploraremos los métodos mágicos de inicialización y representación de objetos en Python. Estos métodos te permiten definir un comportamiento personalizado para crear objetos y representarlos como cadenas legibles y sin ambigüedad para humanos.

__init__

El método __init__ se llama cuando se crea un objeto. Se utiliza para inicializar los atributos del objeto.

Comencemos con un objeto simple. En person.py, cree una clase llamada Person que tenga dos atributos.

class Person:
    def __init__(self, name: str, age: int):
        """
        Inicialice el objeto Person con un nombre y una edad.

        :param name: El nombre de la persona.
        :param age: La edad de la persona.
        """
        self.name = name
        self.age = age

__str__

El método __str__ es llamado por la función integrada str() y la función print() para obtener una representación en cadena legible para humanos del objeto.

    #... (código anterior en person.py)

    def __str__(self) -> str:
        """
        Devuelve una representación en cadena legible para humanos del objeto Person.

        :return: Una cadena que describe a la persona.
        """
        return f"{self.name} tiene {self.age} años."

__repr__

El método __repr__ es llamado por la función integrada repr() y se utiliza en el intérprete interactivo para obtener una representación en cadena que, si es posible, se puede utilizar para recrear el objeto.

    #... (código anterior en person.py)

    def __repr__(self) -> str:
        """
        Devuelve una representación en cadena del objeto Person que se puede utilizar para recrear el objeto.

        :return: Una cadena en el formato 'Person(name, age)'.
        """
        return f"Person('{self.name}', {self.age})"

Ejemplo: Uso de los métodos mágicos básicos

Ahora que hemos definido los métodos mágicos básicos para nuestra clase Person, veamos cómo funcionan en init_repr_example.py:

from person import Person

## Cree un nuevo objeto Person
p = Person("Alice", 30)

## Utilice el método __str__ con la función print
print(p)  ## Salida: Alice tiene 30 años.

## Utilice el método __repr__ en el intérprete interactivo
print(repr(p))  ## Salida: Person('Alice', 30)

Luego, escriba el siguiente comando en la terminal para ejecutar el script.

python init_repr_example.py

Comparación de objetos

En esta sección, exploraremos los métodos mágicos utilizados para la comparación de objetos en Python. Estos métodos te permiten definir una lógica de comparación personalizada para los objetos de tu clase.

__eq__

El método __eq__ se utiliza para determinar si dos objetos son iguales. Es llamado por el operador ==.

    #... (código anterior en person.py)

    def __eq__(self, other: "Person") -> bool:
        """
        Compara dos objetos Person para ver si son iguales.

        :param other: El otro objeto Person con el que se compara.
        :return: True si ambos objetos tienen el mismo nombre y edad, False en caso contrario.
        """
        if isinstance(other, Person):
            return self.name == other.name and self.age == other.age
        return False

__ne__

El método __ne__ se utiliza para determinar si dos objetos no son iguales. Es llamado por el operador !=.

    #... (código anterior en person.py)

    def __ne__(self, other: "Person") -> bool:
        """
        Compara dos objetos Person para ver si son diferentes.

        :param other: El otro objeto Person con el que se compara.
        :return: True si los objetos tienen nombres o edades diferentes, False en caso contrario.
        """
        return not self.__eq__(other)

__lt__

El método __lt__ se utiliza para determinar si un objeto es menor que otro. Es llamado por el operador <.

    #... (código anterior en person.py)

    def __lt__(self, other: "Person") -> bool:
        """
        Compara dos objetos Person para ver si uno es menor que el otro en base a la edad.

        :param other: El otro objeto Person con el que se compara.
        :return: True si la edad del objeto actual es menor que la edad del otro objeto, False en caso contrario.
        """
        if isinstance(other, Person):
            return self.age < other.age
        return NotImplemented

__le__

El método __le__ se utiliza para determinar si un objeto es menor o igual que otro. Es llamado por el operador <=.

    #... (código anterior en person.py)

    def __le__(self, other: "Person") -> bool:
        """
        Compara dos objetos Person para ver si uno es menor o igual que el otro en base a la edad.

        :param other: El otro objeto Person con el que se compara.
        :return: True si la edad del objeto actual es menor o igual que la edad del otro objeto, False en caso contrario.
        """
        if isinstance(other, Person):
            return self.age <= other.age
        return NotImplemented

__gt__

El método __gt__ se utiliza para determinar si un objeto es mayor que otro. Es llamado por el operador >.

    #... (código anterior en person.py)

    def __gt__(self, other: "Person") -> bool:
        """
        Compara dos objetos Person para ver si uno es mayor que el otro en base a la edad.

        :param other: El otro objeto Person con el que se compara.
        :return: True si la edad del objeto actual es mayor que la edad del otro objeto, False en caso contrario.
        """
        if isinstance(other, Person):
            return self.age > other.age
        return NotImplemented

__ge__

El método __ge__ se utiliza para determinar si un objeto es mayor o igual que otro. Es llamado por el operador >=.

    #... (código anterior en person.py)

    def __ge__(self, other: "Person") -> bool:
        """
        Compara dos objetos Person para ver si uno es mayor o igual que el otro en base a la edad.

        :param other: El otro objeto Person con el que se compara.
        :return: True si la edad del objeto actual es mayor o igual que la edad del otro objeto, False en caso contrario.
        """
        if isinstance(other, Person):
            return self.age >= other.age
        return NotImplemented

Ejemplo: Uso de los métodos mágicos de comparación de objetos

Ahora que hemos definido los métodos mágicos de comparación de objetos para nuestra clase Person, veamos cómo funcionan en compare_example.py:

from person import Person

## Crea dos objetos Person
p1 = Person("Alice", 30)
p2 = Person("Bob", 35)

## Utiliza los métodos __eq__ y __ne__
print(p1 == p2)  ## Salida: False
print(p1!= p2)  ## Salida: True

## Utiliza los métodos __lt__, __le__, __gt__ y __ge__
print(p1 < p2)  ## Salida: True
print(p1 <= p2)  ## Salida: True
print(p1 > p2)  ## Salida: False
print(p1 >= p2)  ## Salida: False

Luego, escribe el siguiente comando en la terminal para ejecutar el script.

python compare_example.py

Destrucción de objetos

En esta sección, exploraremos el método mágico de destrucción de objetos en Python. Este método te permite definir un comportamiento personalizado cuando un objeto está a punto de ser destruido.

__del__

El método __del__ es llamado cuando un objeto está a punto de ser destruido. Te permite realizar tareas de limpieza, como cerrar manejadores de archivos o liberar recursos, antes de que el objeto sea recolectado por el recolector de basura.

    #... (código anterior en person.py)

    def __del__(self):
        """
        Limpia el objeto Person antes de ser destruido.
        """
        print(f"Person '{self.name}' está siendo eliminado.")

Ejemplo: Uso del método mágico de destrucción de objetos

Ahora que hemos definido el método mágico de destrucción de objetos para nuestra clase Person, veamos cómo funciona en del_example.py:

from person import Person

## Crea un objeto Person y luego elimínalo
p = Person("Alice", 30)
del p  ## Salida: Person 'Alice' está siendo eliminado.

Luego, escribe el siguiente comando en la terminal para ejecutar el script.

python del_example.py

Es importante tener en cuenta que no se garantiza que el método __del__ sea llamado inmediatamente cuando un objeto ya no es necesario. La eliminación real del objeto depende del mecanismo de recolector de basura del intérprete de Python. El método __del__ es llamado cuando el recolector de basura decide eliminar el objeto de la memoria.

Resumen

En esta serie de tutoriales, exploramos los métodos mágicos de Python, también conocidos como "dunder" métodos (métodos con doble subrayado), que te permiten definir comportamientos personalizados para tus objetos en diversas situaciones.

Al dominar estos métodos mágicos, puedes crear clases y objetos de Python más poderosos y personalizables. Comprender e implementar estos métodos te permitirá escribir código Python más eficiente, limpio y idiomático, lo que hará que tus programas sean más robustos y mantenibles.