Si bien me gusta pensar en mí mismo como un codificador de Python razonablemente competente, un aspecto del lenguaje que nunca he podido entender son los decoradores.
Sé cuáles son (superficialmente), he leído tutoriales, ejemplos, preguntas sobre Stack Overflow, y entiendo la sintaxis, puedo escribir la mía, ocasionalmente uso @classmethod y @staticmethod, pero nunca se me ocurre usar un decorador para resolver un problema en mi propio código Python. Nunca encuentro un problema en el que pienso, "Hmm ... ¡esto parece un trabajo para un decorador!"
Entonces, me pregunto si ustedes podrían ofrecer algunos ejemplos de dónde han usado decoradores en sus propios programas, y espero tener un "¡A-ha!" momento y conseguirlos .
functools.lru_cache
, que hace exactamente lo que Peter dijo, desde Python 3.2, lanzado en febrero de 2011.Respuestas:
Yo uso decoradores principalmente para propósitos de tiempo
fuente
time.clock()
mide el tiempo de CPU. Es posible que desee utilizartime.time()
en su lugar si desea medir el tiempo del reloj de pared.myFunction
correr ...Los he usado para la sincronización.
Como se señaló en los comentarios, desde Python 2.5 puede usar una
with
declaración junto con un objetothreading.Lock
(omultiprocessing.Lock
desde la versión 2.6) para simplificar la implementación del decorador para simplemente:De todos modos, entonces lo usas así:
Básicamente solo pone
lock.acquire()
/lock.release()
a cada lado de la llamada a la función.fuente
Utilizo decoradores para los parámetros de verificación de tipo que se pasan a mis métodos de Python a través de alguna RMI. Entonces, en lugar de repetir el mismo recuento de parámetros, mumbo-jumbo que genera excepciones una y otra vez.
Por ejemplo, en lugar de:
Solo declaro:
y
accepts()
hace todo el trabajo por mí.fuente
@accepts
en PEP 318.isinstance()
función incorporada, como se hace en la implementación PEP 318 del decorador. Dado que suclassinfo
argumento puede ser de uno o más tipos, su uso también mitigaría las objeciones (válidas) de @ Gustavo6046. Python también tiene unaNumber
clase base abstracta, por lo queisinstance(42, numbers.Number)
es posible realizar pruebas muy genéricas .Los decoradores se utilizan para cualquier cosa que desee "envolver" de forma transparente con funcionalidad adicional.
Django los usa para envolver la funcionalidad de "inicio de sesión requerido" en las funciones de visualización , así como para registrar funciones de filtro .
Puede usar decoradores de clases para agregar registros con nombre a las clases .
Cualquier funcionalidad suficientemente genérica que pueda "agregar" al comportamiento de una clase o función existente es un juego justo para la decoración.
También hay una discusión de casos de uso en el grupo de noticias Python-Dev señalado por PEP 318 - Decoradores para funciones y métodos .
fuente
Para las pruebas nasales, puede escribir un decorador que proporcione una función o método de prueba unitaria con varios conjuntos de parámetros:
fuente
La biblioteca Twisted usa decoradores combinados con generadores para dar la ilusión de que una función asincrónica es sincrónica. Por ejemplo:
Con esto, el código que se habría dividido en un montón de pequeñas funciones de devolución de llamada se puede escribir de forma natural como un solo bloque, lo que hace que sea mucho más fácil de entender y mantener.
fuente
Un uso obvio es para iniciar sesión, por supuesto:
fuente
Los uso principalmente para la depuración (envoltura alrededor de una función que imprime sus argumentos y resultados) y verificación (por ejemplo, para verificar si un argumento es del tipo correcto o, en el caso de una aplicación web, si el usuario tiene suficientes privilegios para llamar a un particular método).
fuente
Estoy usando el siguiente decorador para hacer que una función sea segura. Hace que el código sea más legible. Es casi similar al propuesto por John Fouhy, pero la diferencia es que uno trabaja en una sola función y que no hay necesidad de crear un objeto de bloqueo explícitamente.
fuente
Los decoradores se usan para definir las propiedades de una función o como repetitivo que la altera; Es posible, pero contra-intuitivo, que devuelvan funciones completamente diferentes. Mirando las otras respuestas aquí, parece que uno de los usos más comunes es limitar el alcance de algún otro proceso, ya sea registro, creación de perfiles, controles de seguridad, etc.
CherryPy utiliza el envío de objetos para hacer coincidir las URL con los objetos y, finalmente, los métodos. Los decoradores en esos métodos indican si CherryPy incluso tiene permitido usar esos métodos. Por ejemplo, adaptado del tutorial :
fuente
Los usé recientemente, mientras trabajaba en la aplicación web de redes sociales. Para la comunidad / grupos, se suponía que debía autorizar la membresía para crear una nueva discusión y responder a un mensaje de que debe ser miembro de ese grupo en particular. Entonces, escribí un decorador
@membership_required
y lo puse donde lo requería en mi opinión.fuente
Yo uso este decorador para arreglar el parámetro
esto está escrito cuando refactorizo algunas funciones necesitan pasar el argumento "wanN" pero en mis viejos códigos, pasé N o 'N' solamente
fuente
Decorator se puede utilizar para crear fácilmente variables de método de función.
fuente