El argumento principal del libro es que la versión de excepción del código es mejor porque detectará cualquier cosa que pueda haber pasado por alto si intentara escribir su propia comprobación de errores.
Creo que esta afirmación es verdadera solo en circunstancias muy específicas, donde no te importa si la salida es correcta.
No hay duda de que aumentar las excepciones es una práctica segura y segura. Debe hacerlo siempre que sienta que hay algo en el estado actual del programa con el que usted (como desarrollador) no puede o no quiere hacer frente.
Su ejemplo, sin embargo, se trata de atrapar excepciones. Si detecta una excepción, no se está protegiendo de los escenarios que podría haber pasado por alto. Está haciendo exactamente lo contrario: asume que no ha pasado por alto ningún escenario que podría haber causado este tipo de excepción y, por lo tanto, está seguro de que está bien atraparlo (y, por lo tanto, evitar que el programa se cierre). como cualquier excepción no capturada lo haría).
Usando el enfoque de excepción, si ves la excepción ValueError
, saltas una línea. Usando el enfoque tradicional de no excepción, cuenta el número de valores devueltos de split
, y si es menos de 2, salta una línea. ¿Debería sentirse más seguro con el enfoque de excepción, ya que puede haber olvidado otras situaciones de "error" en su verificación de error tradicional, y except ValueError
las detectaría por usted?
Esto depende de la naturaleza de su programa.
Si está escribiendo, por ejemplo, un navegador web o un reproductor de video, un problema con las entradas no debería causar que se bloquee con una excepción no detectada. Es mucho mejor emitir algo de forma remota (incluso si, hablando estrictamente, incorrecto) que dejarlo.
Si está escribiendo una aplicación en la que la corrección es importante (como un software comercial o de ingeniería), este sería un enfoque terrible. Si olvidó algún escenario que genera ValueError
, lo peor que puede hacer es ignorar silenciosamente este escenario desconocido y simplemente omitir la línea. Así es como los errores muy sutiles y costosos terminan en el software.
Podría pensar que la única forma en que puede ver ValueError
en este código es si split
devolvió solo un valor (en lugar de dos). Pero, ¿qué pasa si tu declaración print
comienza más tarde con una expresión que genera ValueError
bajo ciertas condiciones? Esto hará que omita algunas líneas no porque pierdan :
, sino porque print
falla en ellas. Este es un ejemplo de un error sutil al que me refería anteriormente: no notaría nada, simplemente perdería algunas líneas.
Mi recomendación es evitar la captura (¡pero no el aumento!) de excepciones en el código donde producir una salida incorrecta es peor que salir. La única vez que detecto una excepción en dicho código es cuando tengo una expresión realmente trivial, por lo que puedo razonar fácilmente qué puede causar cada uno de los posibles tipos de excepción.
En cuanto al impacto en el rendimiento del uso de excepciones, es trivial (en Python) a menos que se encuentren excepciones con frecuencia.
Si utiliza excepciones para manejar condiciones que ocurren de manera rutinaria, en algunos casos puede pagar un enorme costo de rendimiento. Por ejemplo, supongamos que ejecuta de forma remota algún comando. Puede verificar que el texto de su comando pase al menos la validación mínima (por ejemplo, sintaxis). O puede esperar a que se genere una excepción (lo que ocurre solo después de que el servidor remoto analice su comando y encuentre un problema). Obviamente, el primero es órdenes de magnitud más rápido. Otro ejemplo simple: puede verificar si un número es cero ~ 10 veces más rápido que intentar ejecutar la división y luego capturar la excepción ZeroDivisionError.
Estas consideraciones solo importan si con frecuencia envías cadenas de comando mal formadas a servidores remotos o si recibes argumentos de valor cero que usas para la división.
Nota: asumo que usarías except ValueError
en lugar de solo except
; como otros lo señalaron, y como dice el libro en unas pocas páginas, nunca debes usar bare except
.
Otra nota: el enfoque adecuado sin excepción es contar el número de valores devueltos por split
, en lugar de buscar :
. Este último es demasiado lento, ya que repite el trabajo realizado por split
y puede casi duplicar el tiempo de ejecución.