Diferença entre exceto: e exceto Exceção como e: em Python

140

Os seguintes trechos de código fazem a mesma coisa. Eles capturam todas as exceções e executam o código no except:bloco

Snippet 1 -

try:
    #some code that may throw an exception
except:
    #exception handling code

Snippet 2 -

try:
    #some code that may throw an exception
except Exception as e:
    #exception handling code

Qual é exatamente a diferença nas duas construções?

narendranathjoshi
fonte
7
@ user2725093 essa não é a mesma pergunta. O que você ligou pergunta qual é a diferença entre except Exception, e:e except Exception as e:. Esta pergunta pergunta qual é a diferença entre except:e except Exception as e:.
Dennis

Respostas:

155

No segundo, você pode acessar os atributos do objeto de exceção:

>>> def catch():
...     try:
...         asd()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
global name 'asd' is not defined ("global name 'asd' is not defined",)

Mas ele não pega BaseExceptionou as exceções de sair do sistema SystemExit, KeyboardInterrupte GeneratorExit:

>>> def catch():
...     try:
...         raise BaseException()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in catch
BaseException

Que um nu, exceto:

>>> def catch():
...     try:
...         raise BaseException()
...     except:
...         pass
... 
>>> catch()
>>> 

Consulte a seção Exceções internas dos documentos e a seção Erros e exceções do tutorial para obter mais informações.

agf
fonte
21
Bem, não há mágica aqui. Exceptioné derivado BaseException, é por isso except Exceptionque não pega BaseException. Se você escrever except BaseException, também será capturado. Nua exceptapenas pega tudo.
fjarri
2
Devo salientar que um nu exceptdeve ser o último de uma série de exceptblocos, enquanto você não receberá um erro se colocar except Exceptionantes de outros exceptblocos: eles serão ignorados silenciosamente (se manipularem Exceptionsubclasses). Algo a observar.
Vanessa Phipps
@MatthewPhipps Esse é o ponto, não é? como declarações de caso ou if-else blocos, a execução salta para a primeira condição que corresponda ...
Básico
1
@ Basic Apenas apontando outra diferença entre bare excepte except Exception. "Algo a ser observado" parece um pouco estranho agora, mas na época eu esperava que o Python escolhesse o exceptbloco mais específico , independentemente de onde estivesse, e fiquei um pouco decepcionado ao descobrir o contrário.
Vanessa Phipps
Também é importante notar que a segunda forma só deve ser usada se você não se importa com o que foi a exceção ou deseja lidar com isso de maneira significativa.
21419 Josh J
51
except:

aceita todas as exceções, enquanto

except Exception as e:

só aceita exceções que você deve capturar.

Aqui está um exemplo de um que você não deve pegar:

>>> try:
...     input()
... except:
...     pass
... 
>>> try:
...     input()
... except Exception as e:
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

O primeiro silenciou o KeyboardInterrupt!

Aqui está uma lista rápida:

issubclass(BaseException, BaseException)
#>>> True
issubclass(BaseException, Exception)
#>>> False


issubclass(KeyboardInterrupt, BaseException)
#>>> True
issubclass(KeyboardInterrupt, Exception)
#>>> False


issubclass(SystemExit, BaseException)
#>>> True
issubclass(SystemExit, Exception)
#>>> False

Se você quiser pegar um desses, é melhor fazer

except BaseException:

salientar que você sabe o que está fazendo.


Todas as exceções decorrem BaseExceptione as que você deve capturar no dia-a-dia (aquelas que serão lançadas para o programador) também herdam Exception.

Veedrac
fonte
except(Exception)nunca pega KeyboardInterrupterros. as enão tem nada a ver com isso.
Pandita
2
Eu nunca disse que sim. Eu não mencionei uma vez as e, porque presumi que é óbvio o que faz.
Veedrac
2
Existe um caso em que uma pessoa captura o BaseException E sabe o que está fazendo?
23418 Davos
2
@ Davos Sim, você pode preferir fazer log temporário ou se estiver oferecendo um console ao usuário do qual não deseja exceções SystemExitou que KeyboardInterruptpossa escapar. Não é um caso comum, mas acontece.
Veedrac
14

Existem diferenças com algumas exceções, por exemplo, KeyboardInterrupt.

Lendo PEP8 :

Uma cláusula bare exceto: capturará as exceções SystemExit e KeyboardInterrupt, dificultando a interrupção de um programa com Control-C e pode disfarçar outros problemas. Se você deseja capturar todas as exceções que sinalizam erros no programa, use exceto Exception: (bare except é equivalente a exceto BaseException :).

Diego Herranz
fonte
3

O uso do segundo formulário fornece uma variável (nomeada com base na ascláusula, no seu exemplo e) no exceptescopo do bloco com o objeto de exceção vinculado a ele, para que você possa usar a informação na exceção (tipo, mensagem, rastreamento de pilha, etc.) para lidar com a exceção em uma mansão mais especialmente adaptada.

Silas Ray
fonte
1

Outra maneira de ver isso. Confira os detalhes da exceção:

In [49]: try: 
    ...:     open('file.DNE.txt') 
    ...: except Exception as  e: 
    ...:     print(dir(e)) 
    ...:                                                                                                                                    
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'characters_written', 'errno', 'filename', 'filename2', 'strerror', 'with_traceback']

Existem muitas "coisas" a serem acessadas usando a sintaxe 'as e'.

Esse código foi feito apenas para mostrar os detalhes dessa instância.

jouell
fonte