python exception-handling decorator python-2.6

python - "Outsourcing" de manejo de excepciones a un decorador



exception-handling decorator (3)

  1. Decorador en Python no es lo mismo que el patrón Decorador, aunque hay cierta similitud. No está completamente claro a qué te refieres aquí, pero creo que te refieres al de Python (por lo tanto, es mejor no usar el patrón de palabras)

  2. Los decoradores de Python no son tan útiles para el manejo de excepciones, ya que necesitarías pasar algo de contexto al decorador. Es decir, usted pasaría un contexto global u ocultaría las definiciones de funciones dentro de un contexto externo, lo que requiere, diría, una forma de pensar similar a la de LISP.

  3. En lugar de decoradores puedes usar contextmanagers. Y los uso para ese propósito.

Muchas cláusulas de prueba / excepción / finalización no solo "uglifican" mi código, sino que a menudo me encuentro con el mismo manejo de excepciones para tareas similares. Así que estaba considerando reducir la redundancia al "subcontratarlos" a un ... decorador.

Como estaba seguro de no ser el primero en llegar a esta conclusión, busqué en Google y encontré esta: una recipe ingeniosa que añadía la posibilidad de manejar más de una excepción.

Pero me sorprendió el hecho de que esto no parece ser una práctica ampliamente conocida y utilizada per se, así que me preguntaba si tal vez hay un aspecto que no estaba considerando.

  1. ¿Es falso usar el patrón de decorador para el manejo de excepciones o simplemente lo extrañé todo el tiempo? ¡Por favor iluminame! ¿Cuáles son las trampas?

  2. ¿Existe tal vez incluso un paquete / módulo que admita la creación de dicho manejo de excepciones de una manera razonable?


Básicamente, el inconveniente es que ya no tienes que decidir cómo manejar la excepción en el contexto de la llamada (simplemente dejando que la excepción se propague). En algunos casos, esto puede resultar en una falta de separación de responsabilidad.


La razón principal para mantener los bloques try / except / finally en el propio código es que la recuperación de errores suele ser una parte integral de la función.

Por ejemplo, si tuviéramos nuestra propia función int() :

def MyInt(text): return int(text)

¿Qué debemos hacer si el text no se puede convertir? Devuelve 0 ? Devuelve None ?

Si tiene muchos casos simples, entonces veo que un decorador simple es útil, pero creo que la receta a la que se vinculó intenta hacer demasiado: permite activar una función diferente para cada excepción posible, en casos como los ( varias excepciones diferentes, varias rutas de código diferentes) Recomendaría una función de envoltura dedicada.

Aquí está mi opinión sobre un enfoque de decorador simple:

class ConvertExceptions(object): func = None def __init__(self, exceptions, replacement=None): self.exceptions = exceptions self.replacement = replacement def __call__(self, *args, **kwargs): if self.func is None: self.func = args[0] return self try: return self.func(*args, **kwargs) except self.exceptions: return self.replacement

y uso de la muestra:

@ConvertExceptions(ValueError, 0) def my_int(value): return int(value) print my_int(''34'') # prints 34 print my_int(''one'') # prints 0