Differenza tra tranne: e tranne eccezione come e: in Python


140

Entrambi i seguenti frammenti di codice fanno la stessa cosa. Catturano ogni eccezione ed eseguono il codice nel except:blocco

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 è esattamente la differenza in entrambi i costrutti?


7
@ user2725093 non è la stessa domanda. Quello a cui ti sei collegato chiede qual è la differenza tra except Exception, e:e except Exception as e:. Questa domanda pone la differenza tra except:e except Exception as e:.
Dennis,

Risposte:


155

Nel secondo è possibile accedere agli attributi dell'oggetto eccezione:

>>> 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",)

Ma non cattura BaseExceptiono le eccezioni di sistema-in uscita 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

Che una nuda tranne fa:

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

Consulta la sezione Eccezioni integrate dei documenti e la sezione Errori ed eccezioni dell'esercitazione per ulteriori informazioni.


22
Bene, non c'è magia qui. Exceptionè derivato BaseException, ecco perché except Exceptionnon cattura BaseException. Se scrivi except BaseException, sarà preso anche tu . Nudo exceptcattura tutto.
fjarri,

2
Devo sottolineare che uno nudo exceptdeve essere l'ultimo in una serie di exceptblocchi, mentre non si ottiene un errore se lo si inserisce except Exceptionprima di altri exceptblocchi: verranno ignorati silenziosamente (se gestiscono le Exceptionsottoclassi). Qualcosa a cui fare attenzione.
Vanessa Phipps,

@MatthewPhipps È questo il punto, no? come le istruzioni case o i blocchi if-else, l'esecuzione passa alla prima condizione corrispondente ...
Base

1
@Basic Basta sottolineare un'altra differenza tra nudo excepte except Exception. "Qualcosa a cui prestare attenzione" sembra un po 'strano ora, ma al momento mi aspettavo che Python scegliesse il exceptblocco più specifico , indipendentemente da dove fosse, ed è stato un po' deluso di scoprire diversamente.
Vanessa Phipps,

Vale anche la pena notare che il secondo modulo dovrebbe essere utilizzato solo se non ti interessa quale fosse l'eccezione o desideri gestirla in modo significativo.
Josh J,

51
except:

accetta tutte le eccezioni, mentre

except Exception as e:

accetta solo le eccezioni che si sta significava per la cattura.

Ecco un esempio di quello che non dovresti catturare:

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

Il primo ha messo a tacere il KeyboardInterrupt!

Ecco un breve elenco:

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 vuoi catturare qualcuno di questi, è meglio farlo

except BaseException:

per sottolineare che sai cosa stai facendo.


Tutte le eccezioni derivano BaseExceptione quelle che dovresti catturare quotidianamente (quelle che verranno lanciate per il programmatore) ereditano troppo Exception.


except(Exception)non rileva mai KeyboardInterrupterrori. as enon c'entra niente.
Pandita,

2
Non l'ho mai detto. Non ho menzionato una volta as e, perché ho pensato che fosse ovvio cosa facesse.
Veedrac,

2
C'è un caso in cui una persona potrebbe catturare BaseException E sapere cosa sta facendo?
Davos,

2
@Davos Sì, potresti preferirlo quando effettui la registrazione temporanea o se offri all'utente una console da cui non desideri eccezioni SystemExito KeyboardInterruptda cui scappare. Non è un caso comune, ma succede.
Veedrac,

14

Vi sono differenze con alcune eccezioni, ad esempio KeyboardInterrupt.

Lettura PEP8 :

Una clausola bare tranne: catturerà le eccezioni SystemExit e KeyboardInterrupt, rendendo più difficile interrompere un programma con Control-C e può mascherare altri problemi. Se si desidera rilevare tutte le eccezioni che segnalano errori di programma, utilizzare ad eccezione di Exception: (bare tranne è equivalente a tranne BaseException :).


3

L'utilizzo del secondo modulo fornisce una variabile (denominata in base alla asclausola, nel tuo esempio e) nell'ambito del exceptblocco con l'oggetto dell'eccezione associato ad esso in modo da poter utilizzare le informazioni nell'eccezione (tipo, messaggio, traccia stack, ecc.) Per gestire l'eccezione in un maniero più appositamente adattato.


1

Un altro modo di vedere questo. Dai un'occhiata ai dettagli dell'eccezione:

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']

Ci sono molte "cose" a cui accedere usando la sintassi 'as e'.

Questo codice aveva il solo scopo di mostrare i dettagli di questa istanza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.