Dentro de cualquier clase Python existen unos métodos especiales que se pueden ver con el interprete interactivo de Python, usando la siguiente sintaxis:
dir(nombre_clase)
Se les llama métodos mágicos porque puedes usarlos para crear magia en tus clases. Los nombres de estos métodos están rodeados de dos símbolos de guion bajo de la siguiente forma:
__nombremétodomágico__
Para ver un ejemplo se puede abrir el interprete interactivo y escribir una clase sencilla:
>>> class Juego:
... def juega():
... print('Buena jugada')
Ahora miramos los métodos.
>>> dir(Juego)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__','juega']
Hay métodos mágicos que están destinados a ayudar en la construcción o destrucción de la clase u objeto.
__new__(cls , …): Es el primer método que se inicia cuando se instancia un objeto. Su primer argumento es el nombre de la clase.
__init__(self , …): Es el constructor del objeto. Su primer argumento es el nombre del objeto.
__del__(self): Es el método destructor del objeto donde se pueden incluir cierres de archivos o conexiones. Si no se declara nada, se puede usar como objeto.__del__() para finalizar la instancia.
Otros sirven para modificar el comportamiento del objeto.
__repr__(self): Define el comportamiento cuando se obtiene información del objeto, por ejemplo, escribiendolo directamente en el interprete de python.
__str__(self): Define el comportamiento cuando a un objeto se le asigna el valor de la función str(objeto). La función print(nombr_objeto) devolvería el valor retornado en este método.
Estos son los datos que devuelven estos métodos mágicos:
>>> class Juego:
... pass
...
>>> mijuego = Juego()
>>> mijuego
<__main__.Juego object at 0x1016c0b90>
>>> print(mijuego)
<__main__.Juego object at 0x1016c0b90>
Tras la modificación de los mismos:
>>> class Juego:
... def __repr__(self):
... return 'Clase Juego'
... def __str__(self):
... return 'Juego'
...
>>> mijuego = Juego()
>>> mijuego
Clase Juego
>>> print(mijuego)
Juego
Si se usa una clase u objeto con if o while, el valor que retorna siempre es True salvo que se use el método __bool__() para devolver False o que el método __len__() devuelva cero. Un ejemplo de esto sería:
>>> class Persona:
... def __init__(self,manos):
... self.manos = 2
...
>>> yo = Persona(2)
>>> if yo:
... print('yo es True')
...
yo es True
O también.
>>> class Persona():
... def __init__(self,manos):
... self.manos = 2
... def __bool__(self):
... return False
...
>>> yo = Persona(2)
>>> if yo:
... print('yo es True')
... else:
... print('yo es False')
...
yo es False
Puedes leer mas acerca de los métodos mágicos en A guide to Python’s Magic Methods escrito por Rafe Kettler disponible la siguiente web: https://rszalski.github.io/magicmethods/