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?

¿Fue útil?

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?

Es:

  

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 llamando   return, así que supongo, uno le será devuelta. Sin embargo, no es la   caso:

     

la segunda vuelta se ejecuta

     

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());  
 }  
}  
     

error CS0157 de control no puede dejar el cuerpo de un finalmente cláusula

     

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()  
     

Python devuelve 2, así

     

JavaScript:

<script>  
function ReturnFromFinally()  
{  
 try  
 {  
  return 1;  
 }  
 catch (e)  
 {  
 }  
 finally  
 {  
  return 2;  
 }  
}  
</script>  
<a onclick="alert(ReturnFromFinally());">Click here</a>  
     

JavaScript devuelve 2, así

     

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top