Los decoradores de Python harán que tu código sea mucho mejor

julio 11, 2021 0 Por RenzoC


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

Python ya era legible y amigable para los principiantes antes de que llegaran 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 funcionalidades, sin saturar el panorama y hacer que el código fuera ilegible.

Los decoradores sonmi un ejemplo en horario estelar de una función perfectamente implementada. Se necesita un tiempo para sentirlo, pero vale la pena. Cuando comience a usarlos, notará que no complican demasiado las cosas y hacen que su código sea ordenado y elegante.

En primer lugar: funciones de orden superior

En pocas palabras, los decoradores son una buena forma de manejar funciones de orden superior. ¡Así que echémosles un vistazo primero!

Funciones que devuelven funciones

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

pitón

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

Por supuesto que podríamos haber llamado greet("Simon"). Sin embargo, la conclusión es que podríamos querer poner “Simon” en muchas funciones diferentes. Y si no usamos “Simon” sino algo más complicado, podemos guardar muchas líneas de código comprimiéndolas en una función como simon().

Funciones dentro de otras funciones

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

pitón

La funcion 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.

¿He entendido? ¡Vamos por 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. ¿Te suena extraño? Considera esto:

pitón

La última línea asegura que no necesitamos llamar startstop(roll)() Más; roll() Será suficiente. ¿Sabes cuál es el resultado de esta 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():

Hace lo mismo, pero se pega roll() a startstop() al principio.

Mayor flexibilidad

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

En este caso, sí. Pero una vez que tienes que lidiar con cosas un poco más complicadas, realmente es útil. Por una vez, puede mover todos los decoradores (es decir, 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 hacer esto sin utilizar decoradores. Pero de esta manera hace la vida más fácil ya que ya no tiene que preocuparse por las funciones anidadas y el conteo interminable de paréntesis.

También puede anidar decoradores:

Tenga en cuenta que no hemos definido exectime() de nuevo, pero lo verá en la siguiente sección. Es una función que puede medir la duración de un proceso en Python.

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

¡Comienza el conteo de paréntesis! Imagina que tienes cinco o seis de estas funciones anidadas entre sí. ¿No sería mucho más fácil leer la notación del decorador que este lío anidado?

Incluso puedes usar decoradores en funciones que aceptar los 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. – amar @mydecorator(argument). Sí, puedes hacer todo esto sin decoradores. Pero luego te deseo mucho placer en entender tu código sin un decorador cuando lo vuelvas 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 fundamentalmente imprescindibles.

Medir el tiempo de ejecución

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

¡Diez líneas de código y listo! Además, puede utilizar measuretime() en tantas funciones como desee.

A veces, no desea ejecutar el código de inmediato, solo espere un momento. Aquí es donde un decorador de cámara lenta resulta útil:

Llamada wakeup() De hecho, 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

Suponga que tiene un montón de funciones diferentes que llama en diferentes etapas y pierde la noción de cómo se llama cuando. Con un decorador simple para cada definición de función, puede aportar más claridad. Entonces:

Hay un ejemplo más elaborado aquí. Sin embargo, tenga en cuenta que para comprender este ejemplo deberá verificar ¿Cómo? ‘O’ ¿Qué decorar funciones con argumentos. ¡Todavía vale la pena leerlo!

Reutilizar código

Ni que decir. Si ha definido una función decorator(), puedes espolvorear @decorator en todo tu código. Para ser honesto, ¡no creo que sea más fácil que eso!

Gestión de conexiones

Si tiene funciones a las que solo se debe acceder si un usuario está conectado, esto también es bastante fácil con los decoradores. Te remito a 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 requiera una conexión, @login_required. Bastante simple, diría yo.

Azúcar de sintaxis – o por qué Python es tan dulce

No es como si no lo fuera Revisión de Python o no usar 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: igual de 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 de dulzura tan importante. ¡Azúcar sintáctico para agregar diversión a tu vida! Sin riesgo 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í.