Los decoradores en Python harán que su código sea mucho mejor


Si hay algo que hace que Python sea increíblemente exitoso, es su legibilidad. Todo lo demás depende de eso: si el código es ilegible, es difícil de mantener. Entonces tampoco es amigable para principiantes: un principiante que se quede aturdido por un código ilegible no intentará escribir el suyo algún día.

Python ya era legible y amigable para principiantes antes de que aparecieran los decoradores. Pero a medida que el lenguaje comenzó a usarse para más y más cosas, los desarrolladores de Python sintieron la necesidad de más y más funciones, sin saturar el panorama y hacer que el código fuera ilegible.

Decoradores armi un ejemplo en horario estelar de una función perfectamente implementada. Se necesita un tiempo para entenderlo, pero vale la pena. A medida que empiece a usarlos, notará cómo no complican demasiado las cosas y hacen que su código sea elegante y elegante.

Antes que nada: funciones de orden superior

En pocas palabras, los decoradores son una buena forma de manejar funciones de orden superior. ¡Así que veamos esos primero!

Funciones que devuelven funciones

Digamos que tienes una función greet() – saluda a cualquier objeto que le pase. Y digamos que tiene otra función, simon() – inserta “Simon” donde corresponda. ¿Cómo podemos combinar los dos? Piénselo un minuto antes de mirar a continuación.

pitón

La salida es 'Hello, Simon!'. ¡Espero que tenga sentido para ti!

Por supuesto, podríamos haber llamado greet("Simon"). Sin embargo, el punto es que podríamos querer poner «Simon» en muchas funciones diferentes. Y si no usamos «Simon» sino algo más complicado, podemos guardar un montón de líneas de código empaquetándolo en una función como simon().

Funciones dentro de otras funciones

También podemos definir funciones dentro de otras funciones. ¡Eso es importante porque los decoradores también lo harán! Sin decoradores se ve así:

pitón

La función respect() devuelve una función; respect("yes") devuelve la función de felicitaciones, respect("brother") (o algún otro argumento en lugar de "brother") devuelve la función de insulto. Para llamar a las funciones, ingrese respect("yes")() y respect("brother")(), como una función normal.

¿Entiendo? ¡Entonces estás listo para los decoradores!

El ABC de los decoradores de Python

Funciones con un símbolo @

Probemos una combinación de los dos conceptos anteriores: una función que toma otra función y define una función. ¿Suena alucinante? Considera esto:

pitón

La última línea asegura que no necesitemos llamar startstop(roll)() nunca más; roll() Será suficiente. ¿Sabes cuál es el resultado de esa llamada? Pruébelo usted mismo si no está seguro.

Ahora, como una muy buena alternativa, podríamos insertar esto justo después de definir startstop():

Esto hace lo mismo, pero pega roll() a startstop() al inicio.

Mayor flexibilidad

¿Por qué es útil eso? ¿No consume exactamente tantas líneas de código como antes?

En este caso, sí. Pero una vez que estás lidiando con cosas un poco más complicadas, se vuelve realmente útil. Por una vez, puede mover todos los decoradores (es decir, el def startstop() parte de arriba) en su propio módulo. Es decir, los escribe en un archivo llamado decorators.py y escribe algo como esto en tu archivo principal:

pitón

En principio, puede hacerlo sin utilizar decoradores. Pero de esta manera hace la vida más fácil porque ya no tiene que lidiar con funciones anidadas y conteo interminable de corchetes.

También puede anidar decoradores:

Tenga en cuenta que no hemos definido exectime() todavía, pero lo verá en la siguiente sección. Es una función que puede medir cuánto tiempo tarda un proceso en Python.

Este anidamiento sería equivalente a una línea como esta:

¡El conteo de soportes está comenzando! Imagina que tienes cinco o seis de esas funciones anidadas unas dentro de otras. ¿No sería mucho más fácil leer la notación del decorador que este desorden anidado?

Incluso puedes usar decoradores en funciones que aceptar argumentos. Ahora imagina algunos argumentos en la línea anterior y tu caos estaría completo. Los decoradores lo hacen limpio y ordenado.

Finalmente, incluso puedes agregar argumentos a tus decoradores – como @mydecorator(argument). Sí, puedes hacer todo esto sin decoradores. Pero luego le deseo mucha diversión entendiendo su código libre de decoradores cuando lo vuelva a leer en tres semanas …

Aplicaciones: donde los decoradores cortan la crema

Ahora que espero que te haya convencido de que los decoradores te hacen la vida tres veces más fácil, veamos algunos ejemplos clásicos en los que los decoradores son básicamente indispensables.

Medir el tiempo de ejecución

Digamos que tenemos una función llamada waste time() y queremos saber cuánto tiempo lleva. Bueno, ¡solo usa un decorador!

¡Una docena de líneas de código y listo! Además, puedes usar measuretime() en tantas funciones como desee.

A veces, no desea ejecutar el código de inmediato, espere un poco. Ahí es donde un decorador lento resulta útil:

Vocación wakeup() hace le permite tomar un descanso de 5 minutos, después de lo cual su consola le recuerda que vuelva al trabajo.

Prueba y depuración

Supongamos que tiene una gran cantidad de funciones diferentes a las que llama en diferentes etapas y está perdiendo la visión general sobre cómo se llama y cuándo. Con un decorador simple para cada definición de función, puede aportar más claridad. Al igual que:

Hay un ejemplo más elaborado aquí. Sin embargo, tenga en cuenta que para comprender ese ejemplo, deberá verificar cómo decorar funciones con argumentos. Aún así, ¡vale la pena leerlo!

Reutilizando código

Esto es evidente. Si ha definido una función decorator(), puedes espolvorear @decorator en todas partes de su código. Para ser honesto, ¡no creo que sea más simple que eso!

Manejo de inicios de sesión

Si tiene funcionalidades a las que solo se debe acceder si un usuario está conectado, eso también es bastante fácil con los decoradores. Te referiré al ejemplo completo como referencia, pero el principio es bastante simple: primero, define una función como login_required(). Antes de cualquier definición de función que necesite iniciar sesión, aparece @login_required. Bastante simple, diría yo.

Azúcar sintáctico – o por qué Python es tan dulce

Que no es como si no lo fuera crítico de Python o no utilizando idiomas alternativos donde sea apropiado. Pero Python tiene un gran atractivo: es muy fácil de digerir, incluso cuando no eres un científico informático por formación y solo quieres que las cosas funcionen.

Si C ++ es una naranja, entonces Python es una piña: igualmente nutritiva, pero tres veces más dulce. Los decoradores son solo un factor en la mezcla.

Pero espero que hayas llegado a ver por qué es un factor tan dulce. ¡Azúcar sintáctico para agregar un poco de placer a tu vida! Sin riesgos para la salud, salvo tener los ojos pegados a una pantalla.

Este artículo fue escrito por Rhea Moutafis y fue publicado originalmente en Hacia la ciencia de datos. Puedes leerlo aquí.



Fuente: TNW

Compartir:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para fines de afiliación y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Ver Política de cookies
Privacidad