Métodos mágicos en Python

Métodos mágicos en Python

Este artículo explica los métodos mágicos en Python.

YouTube Video

Métodos mágicos en Python

Los métodos mágicos (métodos especiales) en Python son métodos con nombres especiales que se utilizan para otorgar comportamientos únicos a las clases. Por ejemplo, se caracterizan por estar rodeados de dobles guiones bajos (dunders), como __init__ y __str__. Por lo tanto, también se les llama métodos dunder.

Al definir métodos mágicos, puedes personalizar el comportamiento estándar de las clases. Por ejemplo, definir __add__ te permite cambiar el comportamiento del operador +.

Métodos mágicos para la inicialización y la representación en cadenas

__init__: Método de inicialización

El método __init__ es un constructor que se llama automáticamente cuando se crea una instancia.

1class Person:
2    def __init__(self, name, age):
3        self.name = name
4        self.age = age
5
6person = Person("Alice", 30)
7print(person.name)  # Alice

__str__: Representación en cadena legible para humanos

El método __str__ devuelve una representación en cadena legible para humanos. Es llamado por print() y str().

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __str__(self):
6        return f"Person: {self.name}"
7
8person = Person("Bob")
9print(person)  # Person: Bob

__repr__: Representación en cadena orientada a la depuración

El método __repr__ devuelve una representación en cadena para propósitos de depuración. Se utiliza con repr() y al mostrar en el intérprete.

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __repr__(self):
6        return f"Person(name={self.name!r})"
7
8person = Person("Eve")
9print(repr(person))  # Person(name='Eve')

Sobrecarga de operadores aritméticos

__add__: Operador +

Mediante el uso de métodos mágicos, se pueden sobrecargar los operadores aritméticos. Por ejemplo, el método __add__ permite sobrecargar el operador +.

 1class Vector:
 2    def __init__(self, x, y):
 3        self.x = x
 4        self.y = y
 5
 6    def __add__(self, other):
 7        return Vector(self.x + other.x, self.y + other.y)
 8
 9    def __repr__(self):
10        return f"Vector({self.x}, {self.y})"
11
12    # Other arithmetic magic methods:
13    # def __sub__(self, other):       # Subtraction (-)
14    # def __mul__(self, other):       # Multiplication (*)
15    # def __truediv__(self, other):   # True division (/)
16    # def __floordiv__(self, other):  # Floor division (//)
17    # def __mod__(self, other):       # Modulo (%)
18    # def __pow__(self, other):       # Exponentiation (**)
19
20v1 = Vector(1, 2)
21v2 = Vector(3, 4)
22print(v1 + v2)  # Vector(4, 6)

Otros métodos mágicos aritméticos incluyen los siguientes:.

Método Operador
__add__ +
__sub__ -
__mul__ *
__truediv__ /
__floordiv__ //
__mod__ %
__pow__ **

Personalización de los operadores de comparación

También puedes sobrecargar los operadores de comparación. Por ejemplo, el método __eq__ sobrecarga el operador de igualdad.

 1class Box:
 2    def __init__(self, volume):
 3        self.volume = volume
 4
 5    def __eq__(self, other):
 6        return self.volume == other.volume
 7
 8    def __lt__(self, other):
 9        return self.volume < other.volume
10
11    # Comparison magic methods:
12    # def __eq__(self, other):  # Equal to (==)
13    # def __ne__(self, other):  # Not equal to (!=)
14    # def __lt__(self, other):  # Less than (<)
15    # def __le__(self, other):  # Less than or equal to (<=)
16    # def __gt__(self, other):  # Greater than (>)
17    # def __ge__(self, other):  # Greater than or equal to (>=)
18
19b1 = Box(100)
20b2 = Box(200)
21
22print(b1 == b2)  # False
23print(b1 < b2)   # True

También existen los siguientes métodos mágicos:. Estos métodos mágicos definen comparaciones como la igualdad y el orden entre objetos.

Operador Método mágico
== __eq__
!= __ne__
< __lt__
<= __le__
> __gt__
>= __ge__

Métodos mágicos para tipos contenedor

Puedes crear clases que se comportan como listas o diccionarios.

__len__: Obtener el número de elementos

El método __len__ es un método mágico que devuelve el número de elementos.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __len__(self):
6        return len(self.items)
7
8basket = Basket(["apple", "banana"])
9print(len(basket))  # 2

__getitem__: Acceso por índice

El método __getitem__ se llama al acceder por índice.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __getitem__(self, index):
6        return self.items[index]
7
8basket = Basket(["apple", "banana"])
9print(basket[1])  # banana

__setitem__ y __delitem__: Escritura y eliminación

Los métodos __setitem__ y __delitem__ se llaman cuando se escriben o eliminan elementos.

 1class Basket:
 2    def __init__(self, items):
 3        self.items = items
 4
 5    def __setitem__(self, index, value):
 6        self.items[index] = value
 7
 8    def __delitem__(self, index):
 9        del self.items[index]
10
11basket = Basket(["apple", "banana"])
12basket[1] = "grape"
13del basket[0]
14print(basket.items)  # ['grape']

Métodos mágicos para la iteración

Para hacer que un objeto sea iterable en un bucle for, implementa lo siguiente:.

__iter__ y __next__

 1class Counter:
 2    def __init__(self, limit):
 3        self.limit = limit
 4        self.current = 0
 5
 6    def __iter__(self):
 7        return self
 8
 9    def __next__(self):
10        if self.current >= self.limit:
11            raise StopIteration
12        self.current += 1
13        return self.current
14
15for num in Counter(3):
16    print(num)
17# Output:
18# 1
19# 2
20# 3

Gestor de contexto (instrucción with)

Definiendo los métodos __enter__ y __exit__, puedes implementar procesamiento previo y posterior para la instrucción with.

 1class FileOpener:
 2    def __init__(self, filename):
 3        self.filename = filename
 4
 5    def __enter__(self):
 6        self.file = open(self.filename, 'r')
 7        return self.file
 8
 9    def __exit__(self, exc_type, exc_val, exc_tb):
10        self.file.close()
11
12with FileOpener("example.txt") as f:
13    content = f.read()
14    print(content)

Objetos invocables: __call__

Al definir el método __call__, puedes hacer que una instancia sea invocable como una función.

1class Greeter:
2    def __init__(self, greeting):
3        self.greeting = greeting
4
5    def __call__(self, name):
6        return f"{self.greeting}, {name}!"
7
8hello = Greeter("Hello")
9print(hello("Alice"))  # Hello, Alice!

Resumen

Los métodos mágicos en Python son una forma poderosa de añadir comportamientos naturales e intuitivos a las clases. Cada método tiene un propósito claro, y al implementarlos adecuadamente puedes escribir un código más flexible y Pythonic.

Los métodos mágicos actúan como una 'interfaz invisible' que respalda la manera en que los objetos de Python interactúan y se comportan entre bastidores.

Puedes seguir el artículo anterior utilizando Visual Studio Code en nuestro canal de YouTube. Por favor, también revisa nuestro canal de YouTube.

YouTube Video