Métodos especiales en Python
Métodos especiales, también conocidos como métodos Dunder o métodos Mágicos. Se utilizan para emular el comportamiento de las funciones integradas.
Sus nombres empiezan y terminan en __ (doble guión bajo). Por ejemplo __init__. Normalmente no son invocados directamente por el programador: cuando haces una suma 2 + 2 Python invoca __add__ internamente.
init y repr
__init__ inicializa un objeto cuando se crea una instancia de una clase. __repr__ define la representación técnica del objeto, útil para depuración.
class Car:
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
def __repr__(self):
return f'Car({self.brand!r}, {self.model!r}, {self.year!r})'
my_car = Car('Toyota', 'Corolla', 2023)
print(repr(my_car))
# Output: Car('Toyota', 'Corolla', 2023)
str vs repr
__str__ devuelve una representación legible para el usuario. __repr__ devuelve una representación técnica no ambigua para el desarrollador.
class Car:
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
def __str__(self):
return f'{self.brand} {self.model} ({self.year})'
def __repr__(self):
return f'Car({self.brand!r}, {self.model!r}, {self.year!r})'
my_car = Car('Toyota', 'Corolla', 2023)
print(str(my_car)) # Toyota Corolla (2023)
print(repr(my_car)) # Car('Toyota', 'Corolla', 2023)
La regla general: __str__ es para el usuario final, __repr__ es para el desarrollador.
Métodos de comparación
Permiten usar los operadores de comparación (==, <, >, etc.) con tus propias clases.
| Método | Operador |
|---|---|
__eq__ |
== |
__ne__ |
!= |
__lt__ |
< |
__gt__ |
> |
__le__ |
<= |
__ge__ |
>= |
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __eq__(self, other):
return self.price == other.price
def __lt__(self, other):
return self.price < other.price
def __repr__(self):
return f'{self.name} ({self.price}€)'
p1 = Product('Camiseta', 25)
p2 = Product('Pantalón', 50)
print(p1 == p2) # False
print(p1 < p2) # True
print(p1 > p2) # False
products = [p2, p1]
print(sorted(products))
# Output: [Camiseta (25€), Pantalón (50€)]
Nota:
Al definir __lt__, Python puede usar sorted() y min() / max() sobre objetos de tu clase.
Métodos aritméticos
Permiten usar los operadores matemáticos con tus propias clases.
| Método | Operador |
|---|---|
__add__ |
+ |
__sub__ |
- |
__mul__ |
* |
__truediv__ |
/ |
__floordiv__ |
// |
__mod__ |
% |
__pow__ |
** |
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
def __repr__(self):
return f'Vector({self.x}, {self.y})'
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2) # Vector(4, 6)
print(v2 - v1) # Vector(2, 2)
print(v1 * 3) # Vector(3, 6)
len
Permite usar la función integrada len() con tus propias clases.
class Playlist:
def __init__(self):
self.songs = []
def add(self, song):
self.songs.append(song)
def __len__(self):
return len(self.songs)
playlist = Playlist()
playlist.add('Bohemian Rhapsody')
playlist.add('Stairway to Heaven')
playlist.add('Hotel California')
print(len(playlist))
# Output: 3
contains
Habilita el operador in en tus clases.
class Playlist:
def __init__(self):
self.songs = []
def add(self, song):
self.songs.append(song)
def __contains__(self, song):
return song in self.songs
def __len__(self):
return len(self.songs)
playlist = Playlist()
playlist.add('Bohemian Rhapsody')
playlist.add('Stairway to Heaven')
print('Stairway to Heaven' in playlist) # True
print('Wonderwall' in playlist) # False
call
Hace que un objeto sea invocable como si fuera una función.
class Multiplier:
def __init__(self, factor):
self.factor = factor
def __call__(self, number):
return number * self.factor
double = Multiplier(2)
triple = Multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
Es útil cuando necesitas un objeto que mantenga estado entre llamadas pero que se comporte como una función.
new y del
__new__ crea el objeto antes de que __init__ lo inicialice. Raramente se usa directamente. __del__ se llama cuando el objeto es eliminado por el recolector de basura, tampoco es común.
Links
Special Methods Socratica Youtube 📹
Posteado en Programación con : Python