Python: come ignorare un'eccezione e procedere?


239

Ho una prova ... eccetto il blocco nel mio codice e quando viene lanciata un'eccezione. Voglio solo continuare con il codice perché in quel caso, tutto è ancora in grado di funzionare bene. Il problema è che se si lascia il blocco tranne: vuoto o con #do nulla, si ha un errore di sintassi. Non posso continuare a utilizzare perché non è in un ciclo. C'è una parola chiave che posso usare che dice al codice di andare avanti?

359
except: 
    pass 
+64

eccetto eccezione: pass # importante non ingerire altre eccezioni! 22 feb. 092009-02-22 16:46:45

+8

@Aaron - Sono d'accordo, ma la domanda non era se questa era una buona/cattiva idea 23 feb. 092009-02-23 20:05:24

+15

Questo prenderà SystemExit, KeyboardInterrupt e altre cose che probabilmente non vuoi catturare. 02 gen. 102010-01-02 01:13:31

+1

Non prenderà KeyboardInterrupt. Per esempio: 'while True:' ' provare: ' f = open ('filedoesnotexist.txt') '' eccezione: '' pass' KeyboardInterrupt si ferma ed esce dal codice. 24 lug. 122012-07-24 15:59:51

+14

@ChthonicProject un '' except' nuda attira qualsiasi eccezione, incluso un KeyboardInterrupt, ma solo se succede all'interno di 'try'. Nel tuo esempio, un KeyboardInterrupt può verificarsi prima di 'try' o all'interno di' except', dove non verrà catturato. Se esegui un esempio come 'while True:' 'try: pass'' tranne: pass', troverai che KeyboardInterrupt viene catturato solo il 50% delle volte. Se si 'time.sleep (1)' all'interno di 'try', scoprirai che viene catturato quasi ogni volta. 22 mar. 132013-03-22 08:39:50


12

Prova questo:

try: 
    blah() 
except: 
    pass 

202

Lo standard "NOP" in Python è la dichiarazione pass:

try: 
    do_something() 
except Exception: 
    pass 

A causa degli ultimi eccezione generata essere ricordato in Python, alcuni dei gli oggetti coinvolti nella dichiarazione di lancio delle eccezioni vengono mantenuti dal vivo indefinitamente (in realtà, fino alla prossima eccezione). Nel caso in cui questo è importante per voi e (in genere) non c'è bisogno di ricordare l'ultima eccezione generata, si potrebbe desiderare di effettuare le seguenti operazioni, invece di pass:

try: 
    do_something() 
except Exception: 
    sys.exc_clear() 

questo cancella l'ultima eccezione generata.

+26

Questa è una risposta migliore rispetto a quella accettata perché utilizza "tranne Eccezione:" invece di solo "tranne:" che, come altri hanno sottolineato, ingerisce in modo improprio altre cose che non vuoi prendere come SystemExit e KeyboardInterrupt . 11 lug. 112011-07-11 21:50:28

+4

+1 Elimina anche l'errore che è importante quando si eseguono le unittest e si aspettano eccezioni 26 ott. 112011-10-26 13:50:55

  0

Si noti che 'exc_clear' è stato rimosso in python 3. https: // docs.python.org/3/whatsnew/3.0.html#index-22. Per alcuni modi per risolvere questo problema in Python 3 vedere qui: https://cosmicpercolator.com/2016/01/13/exception-leaks-in-python-2-and-3/ 06 mar. 182018-03-06 18:59:18


114

C'è un nuovo modo per farlo venire in Python 3.4:

from contextlib import suppress 

with suppress(Exception): 
    # your code 

Ecco il commit che hanno aggiunto: http://hg.python.org/cpython/rev/406b47c64480

Ed ecco l'autore, Raymond Hettinger, parlando del più e tutti i tipi di altro piccante Python (bit rilevanti a 43:30): http://www.youtube.com/watch?v=OSGv2VnC0go

Se si voleva emulare la parola chiave except nuda e anche ignorare le cose come KeyboardInterrupt -anche se si spesso non-si potrebbe utilizzare with suppress(BaseException).

Modifica: Sembra che ignored sia stato rinominato suppress prima della versione 3.4.

+1

Non sono sicuro che mi piace questa soluzione ... Immagino che l'idea è che abbiamo sostituito 3 righe con solo 1 (il try, tranne, e pass sono tutti uniti in uno solo.) La cosa principale che mi oppongo è come questo introduce una nuova parola chiave che sembra confermare qualcosa probabilmente non dovresti farlo ... sembra che dovresti sempre registrare almeno le eccezioni che stai intercettando ... 14 ott. 132013-10-14 13:13:09

  0

Quando un'eccezione viene sollevata, continuerà il codice dopo il try/catch o qualunque cosa sia al di fuori del ' con' block? 13 nov. 132013-11-13 07:45:05

+1

Questo è equivalente al wrapping del codice in un 'try ... catch: pass', quindi se viene sollevata un'eccezione all'interno del blocco, l'esecuzione continuerà dopo la fine del blocco. 14 nov. 132013-11-14 08:45:10

+4

@ JackO'Connor Beh, questo lo rende piuttosto inutile ... pensavo che avrebbe semplicemente ignorato le eccezioni come promesso. 04 dic. 132013-12-04 20:21:50

+2

@ArtOfWarfare E se ti dicessi, ti darò un intero, ma a volte te lo darò in una tupla singleton, e non te lo dirò quando faccio l'uno o l'altro; ora il tuo lavoro è di restituirmi sempre l'intero? Forse apprezzerai la possibilità di scrivere qualcosa come 'with suppress (TypeError): return data [0]' (esempio più lungo: http://pastebin.com/gcvAGqEP) 02 mag. 142014-05-02 21:03:25

  0

@Navin Python non può semplicemente fingere che un'eccezione non abbia esiste Supponiamo di avere un'istruzione come 'y = f (x) * g (x)', e quindi 'f (x)' solleva un'eccezione. Anche se Python lo ignora, 'f (x)' non restituisce mai un valore, quindi non c'è modo per Python di assegnare un valore a 'y'. I progettisti avrebbero potuto dire "assumere un valore di Nessuno" o "saltare istruzioni contenenti qualsiasi espressione che non è riuscita a valutare", ma che finirebbe per essere molto confuso. Usare i blocchi 'try' per raggruppare le affermazioni che falliscono insieme mantiene le cose semplici. 14 gen. 152015-01-14 17:14:23

  0

@ JackO'Connor Abbastanza giusto. Speravo ci sarebbe stato un modo per sostituire un'espressione con None se solleva un'eccezione. 14 gen. 152015-01-14 18:07:12

  0

Può essere eseguito in linea? Ad esempio qualcosa come 'supress (myFunc, suppressedException, returnValueOnFailure)'? 23 giu. 152015-06-23 01:43:01

  0

@JeromeJ non puoi farlo direttamente con 'soppressa ', perché è un gestore di contesto. (Per i dettagli su come funzionano i gestori di contesto, vedere qui: https://docs.python.org/3.4/library/stdtypes.html#typecontextmanager) Ma sarebbe piuttosto semplice definire la propria funzione 'callCatchingExceptions' che utilizza' sopprimi 'o un normale blocco 'try' all'interno, se lo si desidera. 24 giu. 152015-06-24 14:01:27

+1

FYI, django ripristina l'uso di 'with suppress (Exception)' nel 2017-09, perché try/except esegue meglio. Controlla questo commit [Reverted "Fixed # 27818 - Sostituito try/except/pass con contextlib.su ...] (https://github.com/django/django/commit/6e4c6281dbb7ee12bcdc22620894edb4e9cf623f) 07 nov. 172017-11-07 07:00:17