Quando vuoi solo fare un tentativo-salvo senza gestire l'eccezione, come lo fai in Python?
Il seguente è il modo giusto per farlo?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Quando vuoi solo fare un tentativo-salvo senza gestire l'eccezione, come lo fai in Python?
Il seguente è il modo giusto per farlo?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Risposte:
try:
doSomething()
except:
pass
o
try:
doSomething()
except Exception:
pass
La differenza è che anche il primo prenderà KeyboardInterrupt
, SystemExit
e cose del genere, che sono derivate direttamente exceptions.BaseException
, non exceptions.Exception
.
Vedi la documentazione per i dettagli:
try: shuti.rmtree(...) except: pass
sopprimerà grossolanamente qualsiasi errore (anche se si scrive shutil
in modo errato con conseguente a NameError
) - per lo meno fareexcept OSError:
È generalmente considerata la migliore pratica per catturare solo gli errori che ti interessano. Nel caso shutil.rmtree
probabilmente è OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
Se si desidera ignorare silenziosamente tale errore, è necessario:
try:
shutil.rmtree(path)
except OSError:
pass
Perché? Di 'che (in qualche modo) passi accidentalmente la funzione un numero intero anziché una stringa, come:
shutil.rmtree(2)
Verrà visualizzato l'errore "TypeError: coercing a Unicode: need string o buffer, int found" - probabilmente non vorrai ignorarlo, che può essere difficile da eseguire il debug.
Se vuoi assolutamente ignorare tutti gli errori, prendi Exception
piuttosto che una semplice except:
dichiarazione. Ancora una volta, perché?
Non specificando un'eccezione viene catturata ogni eccezione, inclusa l' SystemExit
eccezione che ad esempio sys.exit()
utilizza:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Confronta questo con il seguente, che esce correttamente:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Se vuoi scrivere un codice che si comporta sempre meglio, l' OSError
eccezione può rappresentare vari errori, ma nell'esempio sopra vogliamo solo ignorare Errno 2
, quindi potremmo essere ancora più specifici:
import errno
try:
shutil.rmtree(path)
except OSError as e:
if e.errno != errno.ENOENT:
# ignore "No such file or directory", but re-raise other errors
raise
shutil.rmtree
non è il miglior esempio, perché useresti solo ignore_errors=True
per quella funzione ..
Quando vuoi solo provare a catturare senza gestire l'eccezione, come lo fai in Python?
Dipende da cosa intendi per "manipolazione".
Se intendi catturarlo senza intraprendere alcuna azione, il codice che hai pubblicato funzionerà.
Se vuoi dire che vuoi agire su un'eccezione senza fermare l'eccezione dallo stack, allora vuoi qualcosa del genere:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
Innanzitutto cito la risposta di Jack o'Connor da questa discussione . Il thread di riferimento è stato chiuso, quindi scrivo qui:
"C'è un nuovo modo per farlo in arrivo in Python 3.4:
from contextlib import suppress
with suppress(Exception):
# your code
Ecco il commit che lo ha aggiunto: http://hg.python.org/cpython/rev/406b47c64480
Ed ecco l'autore, Raymond Hettinger, che parla di questo e di tutti gli altri tipi di hot di Python: https://youtu.be/OSGv2VnC0go?t=43m23s
La mia aggiunta a questo è l'equivalente di Python 2.7:
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
Quindi lo usi come in Python 3.4:
with ignored(Exception):
# your code
Per completezza:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
Si noti inoltre che è possibile acquisire l'eccezione in questo modo:
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print("Handling run-time error:", err)
... e aumentare nuovamente l'eccezione in questo modo:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
... esempi dal tutorial di Python .
Come ignorare correttamente le eccezioni?
Esistono diversi modi per farlo.
Tuttavia, la scelta dell'esempio ha una soluzione semplice che non copre il caso generale.
Invece di
try:
shutil.rmtree(path)
except:
pass
Fai questo:
shutil.rmtree(path, ignore_errors=True)
Questo è un argomento specifico per shutil.rmtree
. Puoi vedere l'aiuto su di esso procedendo come segue e vedrai che può anche consentire funzionalità su errori.
>>> import shutil
>>> help(shutil.rmtree)
Dal momento che questo copre solo il caso ristretto dell'esempio, dimostrerò ulteriormente come gestirlo se tali argomenti di parole chiave non esistessero.
Poiché quanto sopra copre solo il caso ristretto dell'esempio, dimostrerò ulteriormente come gestirlo se tali argomenti di parole chiave non esistessero.
Puoi importare il suppress
gestore del contesto:
from contextlib import suppress
Ma elimina solo l'eccezione più specifica:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Ignorerai silenziosamente un FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
Dai documenti :
Come con qualsiasi altro meccanismo che sopprime completamente le eccezioni, questo gestore di contesto dovrebbe essere usato solo per coprire errori molto specifici in cui è noto che continuare silenziosamente con l'esecuzione del programma sia la cosa giusta da fare.
Si noti che suppress
e FileNotFoundError
sono disponibili solo in Python 3.
Se vuoi che il tuo codice funzioni anche in Python 2, consulta la sezione successiva:
Quando vuoi semplicemente provare / tranne senza gestire l'eccezione, come lo fai in Python?
Il seguente è il modo giusto per farlo?
try : shutil.rmtree ( path ) except : pass
Per il codice compatibile con Python 2, pass
è il modo corretto di avere un'istruzione che non è operativa. Ma quando si fa un nudo except:
, che è lo stesso di fare except BaseException:
, che comprende GeneratorExit
, KeyboardInterrupt
e SystemExit
, e, in generale, non si vuole per la cattura di queste cose.
In effetti, dovresti essere il più specifico possibile nel nominare l'eccezione.
Ecco parte della gerarchia delle eccezioni di Python (2) e, come puoi vedere, se ricevi eccezioni più generali, puoi nascondere i problemi che non ti aspettavi:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
... and so on
Probabilmente vuoi catturare un OSError qui, e forse l'eccezione che non ti interessa è se non c'è directory.
Possiamo ottenere quel numero di errore specifico dalla errno
libreria e rilanciare se non lo abbiamo:
import errno
try:
shutil.rmtree(path)
except OSError as error:
if error.errno == errno.ENOENT: # no such file or directory
pass
else: # we had an OSError we didn't expect, so reraise it
raise
Nota, un semplice rilancio solleva l'eccezione originale, che è probabilmente quello che vuoi in questo caso. Scritto in modo più conciso, dal momento che non abbiamo davvero bisogno di esplicitamente pass
con il codice nella gestione delle eccezioni:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
Quando vuoi solo provare a catturare senza gestire l'eccezione, come lo fai in Python?
Questo ti aiuterà a stampare qual è l'eccezione :( vale a dire provare a catturare senza gestire l'eccezione e stampare l'eccezione.)
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
Cordiali saluti la clausola else può andare dopo tutte le eccezioni e verrà eseguita solo se il codice nel tentativo non causa un'eccezione.
else
in questo contesto. E per aggiungere che finally
verrà sempre eseguito dopo qualsiasi (o nessuna eccezione).
Avevo bisogno di ignorare gli errori in più comandi e cazzo ha fatto il trucco
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
In Python gestiamo eccezioni simili ad altre lingue, ma la differenza è una differenza di sintassi, ad esempio,
try:
#Your code in which exception can occur
except <here we can put in a particular exception name>:
# We can call that exception here also, like ZeroDivisionError()
# now your code
# We can put in a finally block also
finally:
# Your code...
Di solito faccio solo:
try:
doSomething()
except:
_ = ""
_ = ""
con pass
.
shutil.rmtree(path, ignore_errors=True)
. Questo non si applica alla maggior parte delle funzioni, tuttavia.