Pergunta

Eu encontrei o seguinte comportamento, pelo menos, estranho :

def errors():
    try:
        ErrorErrorError
    finally:
        return 10

print errors()
# prints: 10
# It should raise: NameError: name 'ErrorErrorError' is not defined

A exceção desaparece quando você usa return dentro de uma cláusula finally. Isso é um bug? É isso documentado em qualquer lugar?

Mas a questão real (e a resposta que irá marcar como correto) é:
Qual é a razão dos desenvolvedores do Python para permitir que o comportamento estranho?

Foi útil?

Solução

Você perguntou sobre o raciocínio dos desenvolvedores do Python. Eu não posso falar por eles, mas nenhum outro comportamento faz sentido. Uma função pode devolver um valor, ou pode gerar uma exceção; ele não pode fazer as duas coisas. O objectivo da cláusula "finalmente" é fornecer o código de limpeza que está "garantido" para ser executado, independentemente de exceções. Ao colocar um instrução de retorno em uma cláusula finalmente, você declarou que deseja retornar um valor, não importa o que, independentemente de exceções. Se Python se comportou como você está pedindo e levantou a exceção, ele estaria quebrando o contrato do "finalmente" cláusula (porque isso não devolver o valor que você disse que ele retorne).

Outras dicas

A exceção desaparece quando você usa return dentro de uma cláusula finally. .. Isso é documentado em qualquer lugar?

É:

Se finalmente está presente, ele especifica um manipulador de ‘limpeza’. A cláusula try é executado, incluindo qualquer exceto e cláusulas else. Se ocorrer uma exceção em qualquer das cláusulas e não é tratada, a exceção é salva temporariamente. A cláusula finally é executada. Se houver uma exceção salvo, ele é re-levantada no final da cláusula finally. Se a cláusula finally levanta outra exceção ou executa uma instrução de retorno ou quebra, a exceção salvo é perdido.

Aqui está uma comparação interessante para o retorno no bloco finally, entre - Java / C # / Python / JavaScript: ( arquivo de ligação )

Retorno De Finalmente

Só hoje eu estava ajudando com algum bug em Java e me deparei problema interessante - o que acontece se você usar o retorno dentro de try / catch declaração? Caso a secção finalmente fogo-se ou não? I simplificou o problema a seguinte trecho de código:

O que significa o seguinte código imprimir?

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

Meu palpite inicial seria, que deve imprimir 1, eu estou chamando return, assim que eu supor, um será devolvido. No entanto, não é a caso:

o segundo retorno é executado

Eu entendo a lógica, finalmente secção tem de ser executado, mas de alguma forma eu me sinto desconfortável com isso. Vamos ver o que C # faz neste 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());  
 }  
}  

erro CS0157 de controle não pode deixar o corpo de uma cláusula finally

Eu prefiro muito mais esse comportamento, controle de fluxo não pode ser mexido com na cláusula finally, por isso nos impede de disparar a nós mesmos no pé. Apenas por uma questão de exaustividade, vamos verificar o que outros línguas fazer.

Python:

def a():  
 try:  
  return 1  
 finally:  
  return 2  
print a()  

Python retorna 2, bem

JavaScript:

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

JavaScript retorna 2, bem

Não há nenhuma cláusula finally em C ++ e PHP, então eu não posso experimentar a última duas línguas tenho compilador / intérprete para.

A nossa pequena experiência bem mostrou, que o C # tem a abordagem mais agradável para este problema, mas eu estava muito surpreso ao saber, que todo o outras línguas lidar com o problema da mesma forma.

Retornando de uma finalmente é não uma boa idéia. Eu sei C # especificamente proíbe de fazer isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top