try pass example custom catch python exception-handling

pass - try catch python example



Subir excepción vs. return ¿Ninguna en funciones? (4)

En general, diría que debe lanzarse una excepción si se produce algo catastrófico de lo que no se puede recuperar (es decir, su función trata sobre algún recurso de Internet al que no se puede conectar), y debe devolver None si su función realmente devuelve algo pero nada sería apropiado para devolver (es decir, "Ninguno" si su función intenta hacer coincidir una subcadena en una cadena, por ejemplo).

¿Qué es mejor práctica en una función definida por el usuario en Python: raise una excepción o return None ? Por ejemplo, tengo una función que encuentra el archivo más reciente en una carpeta.

def latestpdf(folder): # list the files and sort them try: latest = files[-1] except IndexError: # Folder is empty. return None # One possibility raise FileNotFoundError() # Alternative else: return somefunc(latest) # In my case, somefunc parses the filename

Otra opción es dejar la excepción y manejarla en el código de la persona que llama, pero creo que es más claro tratar con un FileNotFoundError que con un IndexError . ¿O es mala forma volver a plantear una excepción con un nombre diferente?


Es realmente una cuestión de semántica. ¿Qué significa foo = latestpdf(d) ?

¿Es perfectamente razonable que no hay un archivo más reciente? Entonces seguro, solo devuelve None.

¿Esperas encontrar siempre el último archivo? Levante una excepción. Y sí, volver a plantear una excepción más adecuada está bien.

Si esta es solo una función general que se supone que se aplica a cualquier directorio, haría lo primero y devolvería None. Si el directorio está, por ejemplo, destinado a ser un directorio de datos específico que contiene un conjunto conocido de archivos de la aplicación, me gustaría plantear una excepción.


Haría un par de sugerencias antes de responder a su pregunta, ya que puede responder la pregunta por usted.

  • Siempre nombre sus funciones descriptivas. latestpdf significa muy poco para cualquiera, pero revisando su función latestpdf() obtiene el último pdf. Sugeriría que lo getLatestPdfFromFolder(folder) .

Tan pronto como hice esto, quedó claro lo que debería devolver. Si no hay un pdf, plantee una excepción. Pero espera más.

  • Mantenga las funciones claramente definidas. Dado que no es evidente lo que se supone que debe hacer alguien y no es (aparentemente) obvio cómo se relaciona con obtener el último pdf, le sugiero que lo retire. Esto hace que el código sea mucho más legible.

for folder in folders: try: latest = getLatestPdfFromFolder(folder) results = somefuc(latest) except IOError: pass

¡Espero que esto ayude!


Por lo general, prefiero manejar las excepciones internamente (es decir, try / except inside dentro de la función llamada, posiblemente devolviendo None) porque Python está tipeado dinámicamente. En general, considero que es una llamada de juicio de una forma u otra, pero en un lenguaje de tipado dinámico, hay pequeños factores que inclinan la balanza a favor de no pasar la excepción a la persona que llama:

  1. Cualquier persona que llame a su función no recibirá notificaciones de las excepciones que se pueden lanzar. Se convierte en una especie de forma artística saber qué tipo de excepción estás buscando (y se deben evitar los bloques genéricos excepto).
  2. if val is None es un poco más fácil que except ComplicatedCustomExceptionThatHadToBeImportedFromSomeNameSpace . En serio, odio tener que recordar escribir from django.core.exceptions import ObjectDoesNotExist en la parte superior de todos mis archivos django solo para manejar un caso de uso muy común. En un mundo estáticamente estátizado, deje que el editor lo haga por usted.

Honestamente, sin embargo, siempre es una llamada de juicio, y la situación que describes, donde la función llamada recibe un error que no puede ayudar, es una excelente razón para volver a plantear una excepción que sea significativa. Tiene la idea correcta, pero a menos que sea una excepción, proporcionará información más significativa en un seguimiento de pila que

AttributeError: ''NoneType'' object has no attribute ''foo''

que, nueve de cada diez veces, es lo que verá la persona que llama si devuelve un None no administrado, no se moleste.

(Todo esto me hace desear que las excepciones de Python tengan los atributos de cause de manera predeterminada, como en java, que le permite pasar excepciones a nuevas excepciones para que pueda volver a lanzar todo lo que quiera y nunca perder el origen original del problema).