insertar - crear nueva columna python
¿Cómo hacer que Python falle con gracia? (5)
todos los posibles errores
Las otras respuestas cubren bastante cómo hacer que su programa falle correctamente, pero me gustaría mencionar una cosa: no desea fallar con elegancia todos los errores. Si oculta todos sus errores, no se mostrarán los que indican que la lógica del programa es incorrecta, es decir, los errores que desea ver.
Entonces, si bien es importante conocer sus excepciones, asegúrese de saber exactamente qué excepciones están siendo atrapadas.
Me preguntaba cómo hacer que Python falle en una forma definida por el usuario en todos los errores posibles.
Por ejemplo, estoy escribiendo un programa que procesa una lista (grande) de artículos, y algunos de los artículos pueden no estar en el formato que definí. Si python detecta un error, actualmente solo escupe un feo mensaje de error y detiene todo el proceso. Sin embargo, quiero que muestre el error en algún lugar junto con algún contexto y luego pase al siguiente elemento.
¡Si alguien puede ayudarme con esto, sería muy apreciado!
¡Muchas gracias!
Jason
Cuando Python se ejecuta en una condición de error, lanza una excepción.
La forma de manejar esto es atrapar la excepción y tal vez manejarlo.
Puede consultar la sección sobre excepciones en el tutorial de Python.
Usted expresó un interés en atrapar todas las excepciones. Esto podría hacerse capturando la clase Excepción. de acuerdo con la documentación:
Todas las excepciones integradas que no salen del sistema se derivan de esta clase. Todas las excepciones definidas por el usuario también deben derivarse de esta clase
El mensaje de error feo significa que se genera una excepción. Debes atrapar la excepción.
Un buen lugar para comenzar es la sección del tutorial de Python sobre excepciones.
Básicamente, necesitas envolver tu código en una try...except
bloquear de esta manera:
try:
do_something_dangerous()
except SomeException:
handle_the_error()
Las siguientes son algunas estrategias básicas que utilizo regularmente en mis scripts más que triviales y aplicaciones de tamaño medio.
Consejo 1: Detecte el error en todos los niveles donde tenga sentido continuar procesando. En tu caso, puede estar en el interior del bucle. No tiene que proteger cada línea o cada llamada de función, sino solo los lugares donde hace la diferencia para sobrevivir el error.
Consejo 2: utilice el módulo de registro para informar qué sucedió de forma configurable, independientemente de cómo componga el módulo con otros módulos en aplicaciones más grandes. Comience a importar el registrador de raíz en su módulo, luego, utilizándolo en algunos lugares diferentes, eventualmente podrá descubrir una jerarquía de registro más sensible.
import logging
logger = logging.getLogger()
for item in items:
try:
process(item)
except Exception, exc:
logger.warn("error while processing item: %s", exc)
Consejo 3: defina una "excepción de aplicación", eventualmente puede querer definir una jerarquía de dicha excepción, pero esto se descubrirá mejor cuando surja la necesidad. Use tales excepciones para "salirse" cuando los datos con los que está tratando no son los esperados o para señalar situaciones inconsistentes, mientras los separa de la excepción estándar normal que surge de errores o errores regulares fuera del dominio modelado (errores IO) etc.)
class DomainException(Exception):
"""Life is not what I expected"""
def process(item):
# There is no way that this item can be processed, so bail out quickly.
# Here you are assuming that your caller will report this error but probably
# it will be able to process the other items.
if item.foo > item.bar:
raise DomainException("bad news")
# Everybody knows that every item has more that 10 wickets, so
# the following instruction is assumed always being successful.
# But even if luck is not on our side, our caller will be able to
# cope with this situation and keep on working
item.wickets[10] *= 2
La función principal es el punto de control externo: finalmente, trate aquí las posibles formas en que terminó su tarea. Si esto no fue un script de shell (pero por ejemplo, el procesamiento debajo de un diálogo en una aplicación UI o una operación después de un POST en una aplicación web) solo la forma en que informa el error cambia (y el uso del método de registro separa por completo la implementación del procesamiento desde su interfaz).
def main():
try:
do_all_the_processing()
return 0
except DomainException, exc:
logger.error("I couldn''t finish. The reason is: %s", exc)
return 1
except Exception, exc:
logger.error("Unexpected error: %s - %s", exc.__class__.__name__, exc)
# In this case you may want to forward a stacktrace to the developers via e-mail
return 1
except BaseException:
logger.info("user stop") # this deals with a ctrl-c
return 1
if __name__ == ''__main__'':
sys.exit(main())
use try ... excepto idioma
try:
# code that possibly breaks
except RelevantError: # you need to know what kind of errors you code might produce
# show your message