decorators_python

decoradores en python: como y para qué

Hola, esta vez escribo sobre los decoradores, son una herramienta muy interesante que nos ayuda para el re-uso de código.

que son los decoradores en python

los decoradores son funciones que reciben como parámetros otras funciones y retornan como resultado otras funciones con el objetivo de alterar el funcionamiento original de la función que se pasa como parámetro

el problema

hay funciones que tienen en común muchas funcionalidades, por ejemplo las de manejo de errores de conexión de recursos I/O (que se deben programar siempre que usemos estos recursos) o las de validación de permisos en las respuestas de peticiones de servidores, en vez de repetir el código de rutinas podemos abstraer, bien sea el manejo de error o la respuesta de peticiones, en una función decorador

por ejemplo, es común al manejar recursos como archivos, comunicaciones o bases de datos que el acceso a los mismos pueda fallar por diversas razones que no podemos controlar totalmente, idealmente usamos el código try-except para hacernos cargo, pero si tenemos muchas funciones que van a necesitar exactamente el mismo manejo de error, lo mejor es escribir un decorador que haga el trabajo y pueda re-usarse en vez de copiar-pegar varias veces la misma rutina try-except que solemos realizar.

como hacer un decorador

las funciones decorador reciben como entrada una función y retornan una función, la función que se retorna usualmente se define dentro de la misma función decorador, en este caso, realizamos una función decorador que se llama art_deco la cual ejecuta la función que recibe como entrada (porque recuerden, las funciones en python son también objetos, pueden pasarse de parámetros a otras funciones) en un patrón try-except e implementa una “lógica por defecto” si ocurre un error. Como se puede notar, lo que se regresa es la función en si(el objeto función, llamado en este caso handle_error)

class bad_cat():
    def __init__(self):
        self.nya = 'meow'

    def art_deco(func): 
        """decorator function"""
        def handle_error(*args, **kwargs):
            try:
                func(*args, **kwargs)
                print('we did it')
            except Exception as e:
                descr = 'failed function because of {:}'.format(e)
                print(descr)
        return handle_error

los decoradores usualmente se usan en la definición de las funciones, por ejemplo si vamos a definir una función que lance un error para probar nuestro decorador, la forma para usar este sería poner su nombre después de un @

    @art_deco
    def launch_alert(self):
        """lanza un error cualquiera"""
        raise KeyError('oops')

el código de abajo implementa una prueba completa para comprender bien como funcionan los decoradores, funciona para python 2 y python 3

class bad_cat():
    def __init__(self):
        self.nya = 'meow'

    def art_deco(func): 
        """decorator function"""
        def handle_error(*args, **kwargs):
            try:
                func(*args, **kwargs)
                print('we did it')
            except Exception as e:
                descr = 'failed function because of {:}'.format(e)
                print(descr)
        return handle_error

    @art_deco
    def launch_alert(self):
        """lanza un error cualquiera"""
        raise KeyError('oops')

    @art_deco
    def normal_func(self):
        """usa atributos del propio objeto"""
        k = 'cute_cat says {:}'.format(self.nya)
        print(k)


if __name__ == '__main__':
    neko = bad_cat()  # crear instancia
    neko.launch_alert()  # lanzar una funcion con error
    neko.normal_func()  # lanzar una funcion que usa atributos del objeto

al correrlo, obtenemos algo como:

failed function because of 'oops'
cute_cat says meow
we did it

palabras finales

los decoradores son buenos para sacar de las funciones lógicas que son muy repetitivas para poder re-usarlas a voluntad y también para poder tener estas lógicas separadas y poder mantener nuestro código de manera más fácil y eficiente.

Escrito por Pedro Rivera Wilches

Pedro Rivera Wilches

Soy Ingeniero de Automatizacion Industrial, gran apasionado de la ciencia, la tecnologia y la economia, materias en las que me desempeño profesionalmente. Me gusta la psicologia y analizar el mundo a mi alrededor.

spacer
Loading Facebook Comments ...

Leave a reply