Bienvenidos sean a este post, hoy veremos otro tipo de metodos para las clases.
Estos metodos son sutilmente diferentes con los estaticos vistos en el post anterior porque al igual que los metodos de instancias toman un primer argumento especial que en este caso es el objeto de la clase en si, su uso mas comun es proveer la capacidad de fabrica a una clase, veamos un ejemplo:
>>> class Punto:
... def __init__(self, x, y):
... self.x = x
... self.y = y
... @classmethod
... def desde_tuple(cls, coords):
... return cls(*coords)
... @classmethod
... def desde_punto(cls, punto):
... return cls(punto.x, punto.y)
...
>>>
En este caso creamos una nueva clase llamada Punto, donde primero usaremos a __init__ para iniciar los valores de x e y, observen que tenemos dos funciones y en ambos casos usamos a @classmethod para establecerlas como metodos de clase, esto es similar a cuando hablamos de metodos estaticos dado que las metodos definidos luego de la declaracion anterior se convertiran a este modo, en ambos metodos el primer atributo sera la clase en si, el segundo sera un atributo acorde a lo que devolveremos, en el primer metodo lo usaremos para recibir las dos coordenadas de nuestro punto y como su nombre lo indica lo hara desde un tuple, para el segundo metodo lo haremos desde un punto establecido, en el primer metodo devolveremos las coordenadas almacenadas en la clase y en el segundo metodo debemos devolver los valores de x e y establecidos en el punto creado, para entenderlo mejor vamos a utilizar la clase anterior de la siguiente manera:
>>> p = Punto.desde_tuple((3, 7))
>>> print(p.x, p.y)
3 7
>>>
Creamos una instancia nueva pero esta vez al igual que en los metodos estaticos podemos llamar directamente a las funciones con los datos a almacenar, con esto creamos a nuestra nueva instancia tambien, luego imprimimos los valores de x e y en la instancia creada, pasemos a probar el siguiente metodo:
>>> q = Punto.desde_punto(p)
>>> print(q.x, q.y)
3 7
>>>
Creamos una nueva instancia donde utilizamos al otro metodo donde le pasaremos la instancia creada anteriormente para que obtenga los datos que necesita, si lo chequeamos e imprimimos veremos que obtuvimos el mismo resultado, si observan en ambos ejemplos nunca pasamos la clase porque este se autoreferncia gracias al primer atributo que definimos en la clase, si se preguntan tanto cls como self son nombres que se adoptaron por convencion asi que en este caso para que classmethod sepa que es una referencia a la clase deben usar ese nombre, pero lo bueno de estos metodos y los estaticos es que pueden convivir y colaborar entre ellas, vamos a tomar el ejemplo del post anterior y lo modificaremos de la siguiente manera:
estatico.py
class UtilCadena:
@classmethod
def es_palindromo(cls, t, case_nosensitivo=True):
t = cls._limpiar_texto(t)
if case_nosensitivo:
t = t.lower()
return cls._es_palindromo(t)
@staticmethod
def _limpiar_texto(t):
return ''.join(c for c in t if c.isalnum())
@staticmethod
def _es_palindromo(t):
for c in range(len(t) // 2):
if t[c] != t[-c -1]:
return False
return True
@staticmethod
def get_palabras_unicas(sentencia):
return set(sentencia.split())
En el primer caso cambiamos a nuestro metodo es_palindromo de estatico a tipo clase, como primer cambio agregamos al argumento cls para que tenga a la clase como referencia, despues pasamos el texto y la variable para que sea case sensitive o no, despues modificamos a la variable t donde en lugar de hacer el join utilizamos a una funcion llamada _limpiar_texto de la cual hablaremos luego, despues chequeamos el tema de case sensitive tal como antes pero la unica diferencia es que en lugar de hacer un bucle para devolver un True o un False devuelve el resultado de la funcion _es_palindromo, luego tenemos dos metodos estaticos nuevos.
El primer metodo llamado _limpiar_texto sera de tipo estatico, recibe un texto y en este caso devuelve el resultado la funcion join que utilizabamos antes, se encarga de limpiar todos los caracteres que no sean alfanumericos, el siguiente metodo llamado __es_palindromo se encarga de hacer el bucle que comparara las dos mitades para chequear que sean iguales, en el condicional verificamos que no sean identicas y en caso de cumplirse la condicion devuelve un False si se termina el bucle y nunca se cumplio la condicion devuelve un True porque considera que son iguales, por ultimo seguimos teniendo la misma funcion para obtener las palabras de la frase que informemos, con todas las modificaciones realizadas pasemos a probarlo en nuestro interprete:
>>> from estatico import UtilCadena
>>> print(UtilCadena.es_palindromo("Yo dono rosas, oro no doy"))
True
>>> print(UtilCadena.es_palindromo("Este es un texto de ejemplo"))
False
>>>
En este caso importamos la nueva cadena, luego lo probamos dos veces y podemos ver como nos devolvio los dos estados posibles, como pueden ver sigue funcionando de la misma forma pero podemos ver que el codigo quedo mas simple de leer y lo mejor de todo que quedo mas facil de depurar ante un eventual error, como podemos ver en la clase se puede usar ambos y como uno puede ser utilizado entre ambos.
En resumen, hoy hemos visto que son los metodos de clase, hemos visto como se crean, para que se usan, como nos pueden ser utiles, como pueden ser utilizada junto a los metodos estaticos y los beneficios de poder interactuar entre ambas, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
