retorno come excepción
Pregunta
He encontrado el siguiente comportamiento al menos raro
def errors():
try:
ErrorErrorError
finally:
return 10
print errors()
# prints: 10
# It should raise: NameError: name 'ErrorErrorError' is not defined
La excepción desaparece cuando se utiliza dentro de una cláusula de return
finally
. Es que un error? Se documentó que en cualquier parte?
Pero la pregunta real (y la respuesta voy a marcar como correcto) es:
¿Qué es la razón de que los desarrolladores de Python para permitir que el comportamiento extraño?
Solución
Se le preguntará sobre el razonamiento de los desarrolladores de Python. No puedo hablar por ellos, pero ningún otro comportamiento tiene sentido. Una función o bien puede devolver un valor, o puede provocar una excepción; no puede hacer ambas cosas. El propósito de una cláusula de "fin" es proporcionar el código de limpieza que está "garantizada" para ser ejecutado, independientemente de excepciones. Poniendo una instrucción de retorno en una cláusula por último, se ha declarado que desea devolver un valor, no importa qué, independientemente de excepciones. Si Python se comportó como lo está pidiendo y levantó la excepción, sería romper el contrato de la cláusula "por fin" (debido a que éste deje de devolver el valor que le dijo que para volver).
Otros consejos
La excepción desaparece cuando se utiliza dentro de una cláusula de
return
finally
. .. es la documentada en cualquier lugar?
Si finalmente está presente, especifica un controlador de ‘limpieza’. El bloque try se ejecuta, incluyendo cualquier excepción y cláusulas else. Si se produce una excepción en cualquiera de las cláusulas y no se maneja, la excepción se guarda temporalmente. Se ejecuta la cláusula finalmente. Si hay una excepción salvado, se re-levantada al final de la cláusula finally. Si la cláusula finalmente plantea otra excepción o ejecuta una devolución o declaración de la rotura, se pierde la excepción salvado.
Esta es una comparación interesante para la vuelta en bloque finally, entre - Java / C # / Python / JavaScript: ( archivo de enlace )
Vuelta De Finalmente
Hoy mismo me estaba ayudando con algunos errores en Java y se encontró interesante problema - lo que ocurre si se utiliza de vuelta dentro de try / catch ¿declaración? En caso de que la sección finalmente encender o no? Que simplifica la problema de código siguiente fragmento:
¿Qué hace el siguiente código de impresión a cabo?
class ReturnFromFinally { public static int a() { try { return 1; } catch (Exception e) {} finally{ return 2; } } public static void main(String[] args) { System.out.println(a()); } }
Mi conjetura inicial sería, que debería imprimir
1
, estoy llamandoreturn
, así que supongo, uno le será devuelta. Sin embargo, no es la caso:Me entender la lógica, finalmente, la sección tiene que ser ejecutada, pero de alguna manera me siento incómodo con esto. Veamos lo que hace C # en este caso:
class ReturnFromFinally { public static int a() { try { return 1; } catch (System.Exception e) {} finally { return 2; } } public static void Main(string[] args) { System.Console.WriteLine(a()); } }
Yo prefiero mucho más este comportamiento, el flujo de control no puede ser metido con Por último, en la cláusula, por lo que nos impide disparar a nosotros mismos en el pie. Sólo por el bien de la integridad, vamos a ver qué otras lenguajes.
Python:
def a(): try: return 1 finally: return 2 print a()
JavaScript:
<script> function ReturnFromFinally() { try { return 1; } catch (e) { } finally { return 2; } } </script> <a onclick="alert(ReturnFromFinally());">Click here</a>
No hay ninguna cláusula finally en C ++ y PHP, por lo que no puede probar la última dos lenguas que tienen compilador / intérprete para.
Nuestro pequeño experimento mostró muy bien, de que C # tiene el enfoque más bonito a este problema, pero me ha sorprendido mucho que aprender, que todo el otros idiomas manejar el problema de la misma manera.
Al regresar de un fin es no una buena idea. Yo sé C # específicamente prohíbe hacer esto.