Métodos Mágicos [1]
What are magic methods? They're everything in object-oriented Python. They're special methods that you can define to add "magic" to your classes.Estos métodos normalmente están encerrados entre "__" (doble guion bajo o underscore para los que saben inglés). Un ejemplo es __add__ que se llama cuando se hace entre dos objetos la operación de suma. En el Shell Interactivo de Python le pedimos un poco de ayuda sobre que hace el Entero 4 y nos dice lo siguiente
>>> help(4)
Help on int object:
class int(object)
| int(x[, base]) -> integer
(Resumido)
| __add__(...)
| x.__add__(y) <==> x+y
class Hombre(object):
def __init__(self, nombre):
self.nombre = nombre
def __add__(self, Persona):
if isinstance(Persona, Mujer):
return Hijo()
class Mujer(object):
def __init__(self, nombre):
self.nombre = nombre
def __add__(self, Persona):
if isinstance(Persona, Hombre):
return Hijo()
class Hijo(object):
def __init__(self):
self.nombre = raw_input('Despues de nueve meses has tenido un hijo\nPonle un nombre: ')
>>> from suma_clases import *
>>> juan = Hombre('Juan')
>>> martina = Mujer('Martina')
>>> hijo = juan + martina
Despues de nueve meses has tenido un hijo
Ponle un nombre: Sergio
>>> hijo.nombre
'Sergio'
Se muestra el ejemplo de agregarle el eq a la clase mujer:
class Mujer():
(Resumido)
def __eq__(self, Persona):
if isinstance(Persona, Hombre):
print 'Todos somos iguales'
return True
else:
return False
>>> juan = Hombre('Juan')
>>> martina = Mujer('Martina')
>>> juan == martina
Todos somos iguales
True
Otro cosa que me tocó hacer para un proyecto del trabajo es sobrecargar el __setattr__ de SQLObject para que haga un trigger o update en una tabla cuando se cambiaba cierta columna que es representada como una propiedad de esa clase.
Esto lo hice con el ejemplo que transcribo acá [3].
En mi caso además de modificar la fecha de actualización en la tabla debía agregar unos datos en una tabla que sirve como historial.
Atributos bajo demanda
En python todo funciona como fuera un diccionario por eso se pueden listar todos los atributos llamando al atributo de solo lectura llamada __dict__
>>> juan = Hombre('Juan')
>>> juan.__dict__
{'nombre': 'Juan'}
Usando ese atributo __dict__ podemos por ejemplo agregarle a esa instancia un atributo que no viene en la Clase de la que fue instanciada. Como por ejemplo
>>> juan.__dict__['nombre_falso'] = 'Pedro'
>>> juan.__dict__
{'nombre': 'Juan', 'nombre_falso': 'Pedro'}
>>> juan.nombre_falso
'Pedro'
Algo mucho más interesante para hacer es utilizarlo para hacer que una clase tenga como atributos cualquier cosa que se le pase como parámetros nombrados.
class Example(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
Que se usaría de esta manera.
>>> ej = Example(nombre='Gonzalo', perro='Chicho', facebook=True)
>>> ej.nombre
'Gonzalo'
>>> ej.perro
'Chicho'
>>> ej.facebook
True
El post de magmax es más largo y yo lo voy a partir en pedacitos para ver si además de decirlo con mis palabras lo puedo extender con experiencias propias. Asi que los veo en las siguientes partes.
[0] http://magmax.org/2013/09/30/python-avanzado.html
[1] http://www.rafekettler.com/magicmethods.html
[2] http://www.rafekettler.com/magicmethods.html#comparisons
[3] http://turbogears.org/1.0/docs/SQLObject/AutoUpdateField.html
No hay comentarios.:
Publicar un comentario