Qual é o uso pretendido da else
cláusula opcional da try
declaração?
python
exception-handling
geowa4
fonte
fonte
Respostas:
As instruções no
else
bloco são executadas se a execução cair na parte inferior dotry
- se não houver exceção. Honestamente, nunca encontrei uma necessidade.No entanto, o tratamento de exceções observa:
Portanto, se você possui um método que pode, por exemplo, lançar um
IOError
e deseja capturar exceções, isso ocorre, mas há outra coisa que você deseja fazer se a primeira operação for bem-sucedida e não desejar capturar um IOError de nessa operação, você pode escrever algo como isto:Se você apenas colocar
another_operation_that_can_throw_ioerror()
depoisoperation_that_can_throw_ioerror
,except
ele capturaria os erros da segunda chamada. E se você colocar depois de todo otry
bloco, ele sempre será executado, e não até depois dofinally
. Oelse
permite garantirfinally
bloco eIOError
s que levanta não é pego aquifonte
return
,continue
oubreak
.Há uma grande razão para usar
else
- estilo e legibilidade. Geralmente, é uma boa idéia manter o código que pode causar exceções perto do código que lida com eles. Por exemplo, compare estes:e
O segundo é bom quando
except
não é possível retornar mais cedo ou repetir a exceção. Se possível, eu teria escrito:Nota: Resposta copiada da duplicata postada recentemente aqui , portanto, todo esse material "AskPassword".
fonte
Um uso: teste algum código que deve gerar uma exceção.
(Este código deve ser abstraído para um teste mais genérico na prática.)
fonte
O uso pretendido é ter um contexto para que mais código seja executado, se não houver exceções nas quais se espera que sejam manipuladas.
Esse contexto evita o tratamento acidental de erros que você não esperava.
Mas é importante compreender as condições precisas que causam a cláusula else a prazo, porque
return
,continue
ebreak
pode interromper o fluxo de controle paraelse
.Em suma
A
else
declaração é executado se houver há exceções e se não for interrompida por umreturn
,continue
oubreak
declaração.As outras respostas perdem essa última parte.
Dos documentos:
(Negrito adicionado.) E a nota de rodapé diz:
Requer pelo menos uma cláusula exceto anterior ( consulte a gramática ). Portanto, realmente não é "try-else", é "try-except-else (-finally)", com o
else
(efinally
) sendo opcional.O Tutorial do Python detalha o uso pretendido:
Exemplo de diferenciação
else
versus código após otry
blocoSe você manipular um erro, o
else
bloco não será executado. Por exemplo:E agora,
fonte
Try-except-else é ótimo para combinar o padrão EAFP com a digitação de pato :
Você pode achar que esse código ingênuo é bom:
Essa é uma ótima maneira de ocultar acidentalmente erros graves no seu código. Digitei a limpeza lá, mas o AttributeError que me informaria está sendo engolido. Pior, e se eu o tivesse escrito corretamente, mas ocasionalmente o método de limpeza recebia um tipo de usuário com um atributo com nome errado, causando falhas silenciosas no meio do caminho e deixando um arquivo não fechado? Boa sorte na depuração dessa.
fonte
Acho que é realmente útil quando você precisa fazer a limpeza, mesmo que haja uma exceção:
fonte
Mesmo que você não consiga pensar em usá-lo agora, pode apostar que deve haver um uso para ele. Aqui está uma amostra sem imaginação:
Com
else
:Sem
else
:Aqui você tem a variável
something
definida se nenhum erro for gerado. Você pode remover isso fora dotry
bloco, mas isso requer alguma detecção confusa se uma variável for definida.fonte
something = a[2]; print something
dentro do bloco try:?Há um bom exemplo disso
try-else
no PEP 380 . Basicamente, tudo se resume a manipular exceções diferentes em diferentes partes do algoritmo.É algo como isto:
Isso permite que você escreva o código de manipulação de exceção mais próximo de onde a exceção ocorre.
fonte
De erros e exceções # Manipulando exceções - docs.python.org
fonte
Olhando para a referência Python , parece que
else
é executado depoistry
quando não há exceção. A cláusula else opcional é executada se e quando o controle fluir no final da cláusula try. 2 Exceções na cláusula else não são tratadas pelas cláusulas anteriores, exceto.Mergulhe no python tem um exemplo em que, se eu entendi direito, no
try
bloco eles tentam importar um módulo, quando isso falha, você obtém exceção e vincula o padrão, mas quando funciona, você tem a opção de entrar noelse
bloco e vincular o que é necessário (consulte link para o exemplo e explicação).Se você tentou trabalhar em
catch
bloco, isso poderia gerar outra exceção - acho que é aí que oelse
bloco é útil.fonte
try
bloco.É isso aí. O bloco 'else' de uma cláusula try-except existe para o código que é executado quando (e somente quando) a operação tentada é bem-sucedida. Pode ser usado e pode ser abusado.
Pessoalmente, gosto e uso quando apropriado. Agrupa semanticamente instruções.
fonte
Talvez um uso possa ser:
Talvez isso o leve também a um uso.
fonte
Eu achei a
try: ... else:
construção útil na situação em que você está executando consultas de banco de dados e registrando os resultados dessas consultas em um banco de dados separado do mesmo tipo / tipo. Digamos que eu tenha muitos threads de trabalho, todos lidando com consultas de banco de dados enviadas a uma filaObviamente, se você pode distinguir entre as possíveis exceções que podem ser lançadas, não é necessário usá-lo, mas se o código que reage a um pedaço de código bem-sucedido pode lançar a mesma exceção que o pedaço bem-sucedido, e você não pode simplesmente deixe a segunda exceção possível ir ou retorne imediatamente com sucesso (o que mataria o encadeamento no meu caso), e isso será útil.
fonte
else
Muitas vezes, pode existir um bloco para complementar a funcionalidade que ocorre em cadaexcept
bloco.Nesse caso,
inconsistency_type
é definido em cada bloco exceto, para que o comportamento seja complementado no caso sem erro emelse
.Claro, estou descrevendo isso como um padrão que pode aparecer em seu próprio código algum dia. Nesse caso específico, você apenas define
inconsistency_type
0 antes dotry
bloco.fonte
Aqui está outro lugar onde eu gosto de usar esse padrão:
fonte
continue
- o padrão "sair cedo". Isso permite que você elimine a cláusula "else" e seu recuo, facilitando a leitura do código.Um dos cenários de uso em que posso pensar é as exceções imprevisíveis, que podem ser contornadas se você tentar novamente. Por exemplo, quando as operações no bloco try envolvem números aleatórios:
Mas se a exceção puder ser prevista, você sempre deve escolher a validação antecipadamente em vez de uma exceção. No entanto, nem tudo pode ser previsto, portanto, esse padrão de código tem seu lugar.
fonte
break
interiortry
no final, que é o IMO mais limpo e não precisa doelse
. Tambémcontinue
não é realmente necessário, você pode apenaspass
.Eu achei
else
útil para lidar com um arquivo de configuração possivelmente incorreto:Uma exceção na leitura da
lock
configuração desativa o monitoramento de bloqueios e o ValueErrors registra uma mensagem de aviso útil.fonte
Suponha que sua lógica de programação dependa se um dicionário possui uma entrada com uma determinada chave. Você pode testar o resultado do
dict.get(key)
uso daif... else...
construção ou pode:fonte
Eu adicionaria outro caso de uso que parece simples ao lidar com sessões de banco de dados:
fonte
O
else:
bloco é confuso e (quase) inútil. Também faz parte das declaraçõesfor
ewhile
.Na verdade, mesmo em uma
if
declaração, oelse:
pode ser abusado de maneiras realmente terríveis, criando bugs que são muito difíceis de encontrar.Considere isto.
Pense duas vezes
else:
. Geralmente é um problema. Evite-o, exceto em umaif
declaração e, mesmo assim, considere documentar aelse
condição - para torná-la explícita.fonte
if x > 0: return "yes"
eif x <= 0: return "no"
. Agora uma pessoa vem e muda uma das condições para dizer,x > 1
mas esquece de mudar a outra. Como é esse número reduzido de bugs que seriam cometidos.if else
as cláusulas às vezes têm muitas linhas separadas. DRY é uma boa prática, muito mais frequentemente do que não, na verdade. (desculpe pelo post duplo).