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.