Kiedy chcesz po prostu spróbować wypróbować bez obsługi wyjątku, jak to zrobić w Pythonie?
Czy podążanie za tym jest właściwym sposobem?
try:
shutil.rmtree(path)
except:
pass
Kiedy chcesz po prostu spróbować wypróbować bez obsługi wyjątku, jak to zrobić w Pythonie?
Czy podążanie za tym jest właściwym sposobem?
try:
shutil.rmtree(path)
except:
pass
Odpowiedzi:
try:
doSomething()
except:
pass
lub
try:
doSomething()
except Exception:
pass
Różnica polega na tym, że pierwszy z nich będzie również złapać KeyboardInterrupt
, SystemExit
i takie rzeczy, które pochodzą bezpośrednio z exceptions.BaseException
nie exceptions.Exception
.
Szczegółowe informacje można znaleźć w dokumentacji:
try: shuti.rmtree(...) except: pass
z grubsza tłumi wszelkie błędy (nawet jeśli źle shutil
NameError
except OSError:
Najlepszą praktyką jest wychwytywanie tylko tych błędów, które Cię interesują. W przypadku shutil.rmtree
prawdopodobnie OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
Jeśli chcesz po cichu zignorować ten błąd, wykonaj następujące czynności:
try:
shutil.rmtree(path)
except OSError:
pass
Dlaczego? Powiedzmy, że przypadkowo przekazujesz funkcję liczby całkowitej zamiast ciągu, na przykład:
shutil.rmtree(2)
Daje błąd „TypeError: zmuszanie do Unicode: potrzebujesz ciągu lub bufora, znaleziono int” - prawdopodobnie nie chcesz tego ignorować, co może być trudne do debugowania.
Jeśli zdecydowanie chcesz zignorować wszystkie błędy, złap Exception
raczej niż zwykłe except:
oświadczenie. Znowu dlaczego?
Brak określenia wyjątku przechwytuje każdy wyjątek, w tym SystemExit
wyjątek, który na przykład sys.exit()
wykorzystuje:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Porównaj to z następującymi, które poprawnie wychodzą:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Jeśli chcesz pisać coraz lepiej zachowujący się kod, OSError
wyjątek może reprezentować różne błędy, ale w powyższym przykładzie chcemy tylko zignorować Errno 2
, abyśmy mogli być jeszcze bardziej szczegółowi:
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
nie jest najlepszym przykładem, ponieważ po prostu ignore_errors=True
Kiedy chcesz po prostu spróbować złapać bez obsługi wyjątku, jak to zrobić w Pythonie?
To zależy od tego, co rozumiesz przez „obsługę”.
Jeśli chcesz go złapać bez podejmowania jakichkolwiek działań, opublikowany kod będzie działał.
Jeśli masz na myśli, że chcesz podjąć działanie w stosunku do wyjątku bez zatrzymywania wyjątku przed wejściem na wyższy stos, to potrzebujesz czegoś takiego:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
Najpierw zacytowałem odpowiedź Jacka O'Connora z tego wątku . Odwołany wątek został zamknięty, więc piszę tutaj:
„Jest nowy sposób na zrobienie tego w Pythonie 3.4:
from contextlib import suppress
with suppress(Exception):
# your code
Oto zatwierdzenie, które go dodało: http://hg.python.org/cpython/rev/406b47c64480
A oto autor, Raymond Hettinger, mówiąc o tym i wielu innych upodobaniach Pythona: https://youtu.be/OSGv2VnC0go?t=43m23s
Mój dodatek do tego to odpowiednik Python 2.7:
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
Następnie używasz go jak w Pythonie 3.4:
with ignored(Exception):
# your code
Dla pełności:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
Pamiętaj również, że możesz przechwycić wyjątek w następujący sposób:
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print("Handling run-time error:", err)
... i ponownie podnieś wyjątek w ten sposób:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
... przykłady z samouczka języka python .
Jak poprawnie zignorować wyjątki?
Można to zrobić na kilka sposobów.
Jednak wybór przykładu ma proste rozwiązanie, które nie obejmuje ogólnego przypadku.
Zamiast
try:
shutil.rmtree(path)
except:
pass
Zrób to:
shutil.rmtree(path, ignore_errors=True)
Jest to argument specyficzny dla shutil.rmtree
. Możesz zobaczyć pomoc na ten temat, wykonując następujące czynności, a zobaczysz, że może ona również umożliwiać działanie w przypadku błędów.
>>> import shutil
>>> help(shutil.rmtree)
Ponieważ dotyczy to tylko wąskiego przypadku przykładu, pokażę dalej, jak sobie z tym poradzić, jeśli te argumenty słów kluczowych nie istnieją.
Ponieważ powyższe dotyczy tylko wąskiego przypadku przykładu, pokażę dalej, jak sobie z tym poradzić, jeśli te argumenty słów kluczowych nie istnieją.
Możesz zaimportować suppress
menedżera kontekstu:
from contextlib import suppress
Ale tylko pomiń najbardziej specyficzny wyjątek:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Po cichu zignorujesz FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
Z dokumentów :
Podobnie jak w przypadku każdego innego mechanizmu, który całkowicie eliminuje wyjątki, ten menedżer kontekstu powinien być używany tylko do pokrywania bardzo specyficznych błędów, o których wiadomo, że cicho kontynuuje wykonywanie programu.
Zauważ, że suppress
i FileNotFoundError
są dostępne tylko w Pythonie 3.
Jeśli chcesz, aby Twój kod działał również w Pythonie 2, zobacz następną sekcję:
Jeśli chcesz po prostu spróbować / oprócz bez obsługi wyjątku, jak to zrobić w Pythonie?
Czy podążanie za tym jest właściwym sposobem?
try : shutil.rmtree ( path ) except : pass
W przypadku kodu zgodnego z Python 2 pass
jest to poprawny sposób, aby uzyskać instrukcję, której nie można pominąć. Ale kiedy robisz gołe except:
, że to samo, co robi except BaseException:
, które zawiera GeneratorExit
, KeyboardInterrupt
i SystemExit
, w ogóle, nie chcesz, aby złapać te rzeczy.
W rzeczywistości powinieneś nazwać wyjątek tak dokładnie, jak możesz.
Oto część hierarchii wyjątków języka Python (2) i, jak widać, jeśli złapiesz bardziej ogólne wyjątki, możesz ukryć nieoczekiwane problemy:
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
Prawdopodobnie chcesz złapać tutaj błąd OSErrr, a być może wyjątkiem, na którym ci nie zależy, jest brak katalogu.
Możemy uzyskać ten konkretny numer błędu z errno
biblioteki i poprawić go, jeśli go nie mamy:
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
Uwaga: nagie przebicie podnosi pierwotny wyjątek, który prawdopodobnie jest tym, czego chcesz w tym przypadku. Napisane bardziej zwięźle, ponieważ tak naprawdę nie musimy jawnie używać pass
kodu w obsłudze wyjątków:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
Kiedy chcesz po prostu spróbować złapać bez obsługi wyjątku, jak to zrobić w Pythonie?
Pomoże to wydrukować wyjątek :( tj. Spróbuj złapać bez obsługi wyjątku i wydrukować wyjątek).
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
Do Twojej wiadomości klauzula else może przejść po wszystkich wyjątkach i zostanie uruchomiona tylko wtedy, gdy kod w try nie spowoduje wyjątku.
else
w tym kontekście. I dodać, że zawszefinally
będzie działać po jakimkolwiek (lub bez wyjątku).
Musiałem zignorować błędy w wielu poleceniach i kurwa to załatwiło
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
W Pythonie obsługujemy wyjątki podobne do innych języków, ale różnica polega na pewnej różnicy składni, na przykład:
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...
Zwykle po prostu robię:
try:
doSomething()
except:
_ = ""
_ = ""
z pass
.
shutil.rmtree(path, ignore_errors=True)
. Nie dotyczy to jednak większości funkcji.