Pregunta

Recientemente comencé a experimentar con decoradores Python (y funciones de orden superior) porque parecía que podrían hacer que las pruebas de mi unidad Django fueran más concisas. por ejemplo, en lugar de escribir:

def visit1():
    login()
    do_stuff()
    logout()

En su lugar podría hacer

@handle_login
def visit1():
    do_stuff()

Sin embargo, después de experimentar un poco, descubrí que los decoradores no son tan simples como esperaba. Primero, estaba confundido por la diferente sintaxis de decorador que encontré en diferentes ejemplos, hasta que aprendí que los decoradores se comportan de manera muy diferente cuando tomar argumentos . Luego intenté decorar un método, y finalmente aprendí que no funcionaba porque primero tenía que convierta mi decorador en un descriptor agregando un método __get__. Durante todo este proceso, terminé confundido más de unas pocas veces y todavía encuentro que depurar esto & "; Decorado &"; El código es más complicado de lo que normalmente es para Python. Ahora estoy reevaluando si realmente necesito decoradores en mi código, ya que mi motivación inicial fue ahorrar un poco de escritura, no porque hubiera algo que realmente requiriera funciones de orden superior.

Entonces, mi pregunta es: ¿deben usarse los decoradores de forma liberal o moderada? ¿Es cada vez más Pythonic evitar usarlos?

¿Fue útil?

Solución

Los decoradores están bien en su lugar y definitivamente no deben evitarse, cuando sea apropiado ;-). Veo que su pregunta significa esencialmente & Quot; OK, así que cuando son se apropian de & Quot ;?

Agregar un código de prefijo y / o postfix alrededor de algunos pero no todos los métodos de algunas clases es un buen ejemplo. Si se tratara de todos los métodos, un decorador class para ajustar todos los métodos sería mejor que repetir @thisonetoo sin fin ;-). Si alguna vez está en una luna azul, entonces no vale la pena refactorizar a los envoltorios (decoradores u otros). En el medio, hay un gran terreno donde los decoradores son bastante adecuados.

Se reduce a una de las reglas de oro de la programación: DRY, para no repetirse. Cuando vea que su código se vuelve repetitivo, debe refactorizar la repetición, y los decoradores son una herramienta excelente para eso, aunque están lejos de ser el único (métodos y funciones auxiliares, metaclases personalizadas, generadores y otros iteradores, administradores de contexto ... muchas de las características que agregamos a Python en los últimos años pueden considerarse mejor como DRY-helpers, ¡formas más fáciles y suaves de descifrar esta o aquella forma frecuente de repetición!).

Si no hay repetición, no hay un llamado real a la refactorización, por lo tanto (en particular) no hay una necesidad real de decoradores, en tales casos, YAGNI (Y'Ain't Gonna Need It) puede superar DRY; -).

Otros consejos

Alex ya respondió a tu pregunta bastante bien, lo que agregaría son decoradores, hacen que tu código sea MUCHO más fácil de entender. (A veces, incluso si lo está haciendo solo una vez).

Por ejemplo, inicialmente, escribo mis vistas de Django, sin pensar en ninguna autorización. Y cuando termine de escribirlos, puedo ver cuáles necesitan usuarios autorizados y simplemente poner un @login_required para ellos.

Entonces, cualquiera que venga después de mí puede ver de un vistazo qué vistas están protegidas por autenticación.

Y, por supuesto, están mucho más SECOS y lo ponen en todas partes.

si no request.user.is_authenticated ():     return HttpResponseREdiect (..)

Los decoradores son una forma de sacar un Aspecto común de su código.

Programación orientada a aspectos los proponentes le dirán que hay tantos aspectos comunes ese AOP es esencial y central. De hecho, puede leer un debate tonto sobre este tema aquí:

Programación orientada a aspectos versus programación orientada a objetos

Hay algunos casos de uso comunes para AOP. Puedes leer algunos aquí:

¿Utiliza AOP (Programación Orientada a Aspectos) en software de producción?

Hay algunas preocupaciones transversales para las cuales los decoradores son útiles.

  • Controles de acceso (" seguridad ") Autenticación, autorización, permisos, propiedad

  • Registro (incluidas ayudas de depuración y auditoría)

  • Almacenamiento en caché (a menudo una implementación de Memoization )

  • Algún manejo de errores podría ser un aspecto común y, por lo tanto, adecuado para la implementación del decorador.

Hay muy pocos otros patrones de diseño que sean verdaderamente transversales y merezcan un decorador AOP.

Si tiene el mismo código al principio y al final de muchas funciones, creo que eso justificaría la complejidad adicional de usar un decorador.

En lugar de usar una plantilla agradable (pero quizás compleja) para un sitio web con muchas páginas, realmente ahorra tiempo y agrega claridad al final.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top