Los métodos Magic en Python, también conocidos como métodos dunder (porque tienen guiones bajos dobles al principio y al final de sus nombres), nos permiten definir el comportamiento de nuestros objetos para diversas operaciones. Permiten un comportamiento personalizado y pueden hacer que nuestras clases actúen como tipos integrados. En este blog, exploraremos diferentes categorías de métodos mágicos, brindaremos explicaciones detalladas y daremos ejemplos prácticos y casos de uso.
Estos métodos mágicos controlan cómo se accede, modifica o elimina los atributos de tus objetos.
__getattr__: Se llama cuando un atributo no se encuentra en un objeto.
__getattribute__: Llamado incondicionalmente para acceder a cualquier atributo.
Ejemplo: acceso a atributos personalizados con registro
class LoggedAttributes: def __init__(self, name): self.name = name def __getattr__(self, item): print(f"Accessing non-existent attribute: {item}") return None def __getattribute__(self, item): print(f"Getting attribute: {item}") return super().__getattribute__(item) # Usage obj = LoggedAttributes("Alice") print(obj.name) # Output: Getting attribute: name\nAlice print(obj.age) # Output: Accessing non-existent attribute: age\nNone
Caso de uso práctico: Registrar el acceso a los atributos en un escenario de depuración para rastrear cuándo y cómo se accede a los atributos o se modifican.
__setattr__: se llama cuando se intenta una asignación de atributo.
__delattr__: se llama cuando se intenta eliminar un atributo.
Ejemplo: modificación de atributos personalizados con validación
class Person: def __init__(self, name, age): self.name = name self.age = age def __setattr__(self, key, value): if key == "age" and valueCaso de uso práctico: Aplicar reglas o restricciones de validación al configurar o eliminar atributos.
2. Métodos de contenedor
Estos métodos mágicos permiten que tus objetos se comporten como contenedores (listas, diccionarios, etc.).
__len__, __getitem__, __setitem__, __delitem__ y __iter__
__len__: Devuelve la longitud del contenedor.
__getitem__: recupera un elemento en un índice o clave determinado.
__setitem__: establece un elemento en un índice o clave determinado.
__delitem__: elimina un elemento en un índice o clave determinado.
__iter__: Devuelve un objeto iterador.
Ejemplo: objeto tipo lista personalizado
class CustomList: def __init__(self): self._items = [] def __len__(self): return len(self._items) def __getitem__(self, index): return self._items[index] def __setitem__(self, index, value): self._items[index] = value def __delitem__(self, index): del self._items[index] def __iter__(self): return iter(self._items) def append(self, item): self._items.append(item) # Usage cl = CustomList() cl.append(1) cl.append(2) cl.append(3) print(len(cl)) # Output: 3 print(cl[1]) # Output: 2 for item in cl: print(item) # Output: 1 2 3
Caso de uso práctico: Crear una clase de colección personalizada que necesita un comportamiento especializado o métodos adicionales y al mismo tiempo admitir operaciones de lista estándar.
Estos métodos definen cómo los objetos de tu clase interactúan con operaciones numéricas y comparaciones.
Ejemplo: Clase de número complejo personalizada
class Complex: def __init__(self, real, imag): self.real = real self.imag = imag def __add__(self, other): return Complex(self.real other.real, self.imag other.imag) def __sub__(self, other): return Complex(self.real - other.real, self.imag - other.imag) def __repr__(self): return f"({self.real} {self.imag}i)" # Usage c1 = Complex(1, 2) c2 = Complex(3, 4) print(c1 c2) # Output: (4 6i) print(c1 - c2) # Output: (-2 -2i)
Caso de uso práctico: Implementación de tipos numéricos personalizados como números complejos, vectores o matrices.
Ejemplo: implementar pedidos totales para una clase personalizada
from functools import total_ordering @total_ordering class Book: def __init__(self, title, author): self.title = title self.author = author def __eq__(self, other): return (self.title, self.author) == (other.title, other.author) def __lt__(self, other): return (self.title, self.author)Caso de uso práctico: Permitir ordenar o comparar objetos personalizados, útil en estructuras de datos como montones, árboles de búsqueda binarios o simplemente al ordenar listas de objetos personalizados.
4. Métodos de contenedores: caso de uso práctico
Diccionario personalizado con teclas que no distinguen entre mayúsculas y minúsculas
Crear un objeto similar a un diccionario que trata las claves sin distinguir entre mayúsculas y minúsculas.
Ejemplo: Diccionario que no distingue entre mayúsculas y minúsculas
class CaseInsensitiveDict: def __init__(self): self._data = {} def __getitem__(self, key): return self._data[key.lower()] def __setitem__(self, key, value): self._data[key.lower()] = value def __delitem__(self, key): del self._data[key.lower()] def __contains__(self, key): return key.lower() in self._data def keys(self): return self._data.keys() def items(self): return self._data.items() def values(self): return self._data.values() # Usage cid = CaseInsensitiveDict() cid["Name"] = "Alice" print(cid["name"]) # Output: Alice print("NAME" in cid) # Output: TrueCaso de uso práctico: Crear diccionarios donde las claves deben tratarse sin distinguir entre mayúsculas y minúsculas, lo que resulta útil para manejar entradas de usuario, ajustes de configuración, etc.
Conclusión
Los métodos mágicos proporcionan una forma poderosa de personalizar el comportamiento de sus objetos en Python. Comprender y utilizar eficazmente estos métodos puede hacer que sus clases sean más intuitivas y se integren perfectamente con las funciones y operadores integrados de Python. Ya sea que esté implementando tipos numéricos personalizados, contenedores o patrones de acceso a atributos, los métodos mágicos pueden mejorar enormemente la flexibilidad y funcionalidad de su código
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3