Jak prawidłowo ignorować wyjątki

Jeśli po prostu chcesz spróbować-z wyjątkiem bez obsługi wyjątku, jak to zrobić w Pythonie?

Czy to jest właściwy sposób?

try:
    shutil.rmtree(path)
except:
    pass
Author: Peter Mortensen, 2009-04-08

11 answers

try:
  doSomething()
except: 
  pass

Lub

try:
  doSomething()
except Exception: 
  pass

Różnica polega na tym, że pierwszy z nich również złapie KeyboardInterrupt, SystemExit i tego typu rzeczy, które pochodzą bezpośrednio z exceptions.BaseException, a nie exceptions.Exception.
zobacz dokumentację po szczegóły:

 866
Author: vartec,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-08 16:37:49

Ogólnie uważa się, że najlepszą praktyką jest wyłapywanie tylko tych błędów, które Cię interesują. W przypadku shutil.rmtree to 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:

try:
    shutil.rmtree(path)
except OSError:
    pass
Dlaczego? Powiedzmy, że (jakoś) przypadkowo przekazujesz funkcji liczbę całkowitą zamiast ciągu znaków, jak:
shutil.rmtree(2)

Wyświetli błąd "TypeError: coering to Unicode: need string or buffer, int found" - prawdopodobnie nie chcesz tego ignorować, co może być trudne do debugowania.

Jeśli zdecydowanie chcesz zignorować wszystkie błędy, Złap Exception zamiast nagiego except: stwierdzenia. Znowu, dlaczego?

Nie określanie wyjątku każdy wyjątek , w tym wyjątek SystemExit, który na przykład sys.exit() używa:

>>> try:
...     sys.exit(1)
... except:
...     pass
... 
>>>

Porównaj to z poniższym, który poprawnie wychodzi:

>>> 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, więc możemy być jeszcze bardziej konkretni:

try:
    shutil.rmtree(path)
except OSError, e:
    if e.errno == 2:
        # suppress "No such file or directory" error
        pass
    else:
        # reraise the exception, as it's an unexpected error
        raise

Można też import errno i zmień if na if e.errno == errno.ENOENT:

 120
Author: dbr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-25 09:58:57

Jeśli chcesz po prostu spróbować złapać bez obsługi wyjątku, jak to zrobić w Pythonie?

To zależy co masz na myśli mówiąc " obsługa."

Jeśli chcesz go złapać bez podejmowania żadnych działań, opublikowany kod zadziała.

Jeśli masz na myśli, że chcesz podjąć działania na wyjątku bez zatrzymywania wyjątku przed wejściem do stosu, to chcesz coś takiego:

try:
    do_something()
except:
    handle_exception()
    raise  #re-raise the exact same exception that was thrown
 107
Author: Jason Baker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-08 16:32:32

Najpierw cytuję odpowiedź Jacka o ' Connora z tego wątku . Wątek został zamknięty więc piszę tutaj:

"jest nowy sposób, aby to zrobić w Pythonie 3.4:

from contextlib import suppress

with suppress(Exception):
    # your code

Oto commit, który go dodał: http://hg.python.org/cpython/rev/406b47c64480

A oto autor, Raymond Hettinger, mówi o tym i wszystkich innych pythonowych hotness: https://youtu.be/OSGv2VnC0go?t=43m23s

Moim dodatkiem do tego jest Odpowiednik Pythona 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
 65
Author: Jabba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-13 12:43:22

Dla kompletnoś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"

...z tutoriala Pythona .

Zauważ również, że możesz przechwycić wyjątek w następujący sposób:

>>> try:
...     this_fails()
... except ZeroDivisionError as detail:
...     print 'Handling run-time error:', detail
 54
Author: cbare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-13 22:16:54

Jak właściwie ignorować wyjątki?

Można to zrobić na kilka sposobów.

Wybór przykładu ma jednak proste rozwiązanie, które nie obejmuje ogólnego przypadku.

Specyficzne dla przykładu:

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 nim, wykonując następujące czynności, a zobaczysz, że może również zezwalać na funkcjonalność w przypadku błędów jako cóż.

>>> import shutil
>>> help(shutil.rmtree)

Ponieważ dotyczy to tylko wąskiej litery przykładu, zademonstruję, jak sobie z tym poradzić, jeśli te argumenty słów kluczowych nie istniały.

Podejście ogólne

Ponieważ powyższe dotyczy tylko wąskiej litery przykładu, zademonstruję dalej, jak sobie z tym poradzić, jeśli te argumenty słów kluczowych nie istniały.

Nowy w Pythonie 3.4:

Możesz zaimportować suppress menedżer kontekstu:

from contextlib import suppress

Ale tylko tłumić najbardziej konkretne wyjątek:

with suppress(FileNotFoundError):
    shutil.rmtree(path)

Po cichu zignorujesz FileNotFoundError:

>>> with suppress(FileNotFoundError):
...     shutil.rmtree('bajkjbkdlsjfljsf')
... 
>>> 

Z docs :

Jak w przypadku każdego innego mechanizmu, który całkowicie tłumi wyjątki, ten menedżer kontekstu powinien być używany tylko do pokrycia bardzo konkretnych błędów gdzie ciche kontynuowanie wykonywania programu jest znane jako słusznie.

Zauważ, że suppress i {[12] } są dostępne tylko w Pythonie 3.

Jeśli chcesz, aby Twój kod działał w Pythonie 2 jak również, zobacz następną sekcję:

Python 2 & 3:

Kiedy tylko chcesz spróbować/z wyjątkiem bez obsługi wyjątku, jak to się robi w Pythonie?

Czy to jest właściwy sposób, aby to zrobić?

try :
    shutil.rmtree ( path )
except :
    pass

Dla kodu zgodnego z Pythonem 2, {[15] } jest poprawnym sposobem na wyrażenie, które jest no-op. ale kiedy robisz nagie except:, to jest to samo, co Robienie except BaseException:, które zawiera GeneratorExit, KeyboardInterrupt, i SystemExit, i w ogóle, nie chcesz łap to.

W rzeczywistości, powinieneś być tak dokładny w nazywaniu wyjątku, jak tylko możesz.

Oto część hierarchii WYJĄTKÓW Pythona (2) i jak widzisz, Jeśli złapiesz bardziej ogólne wyjątki, możesz ukryć problemy, których się nie spodziewałeś:

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ć OSError tutaj, a może wyjątkiem, który cię nie obchodzi, jest to, czy nie ma katalogu.

Możemy uzyskać ten konkretny numer błędu z errno biblioteka, i reraise jeśli nie mamy tego:

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, gołe podbicie podnosi oryginalny wyjątek, który prawdopodobnie jest tym, czego chcesz w tym przypadku. W przeciwieństwie do innych języków, nie ma potrzeby używania kodu do obsługi wyjątków.]}

try:
    shutil.rmtree(path)
except OSError as error:
    if error.errno != errno.ENOENT: # no such file or directory
        raise 
 40
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-19 14:38:26

@Jeśli chcesz po prostu spróbować złapać bez obsługi wyjątku, jak to zrobić w Pythonie?

To pomoże Ci wydrukować co to jest wyjątek: (tzn. spróbuj złapać bez obsługi wyjątku i wydrukuj wyjątek.)

import sys
....
try:
    doSomething()
except:
    print "Unexpected error:", sys.exc_info()[0]

...

Reg, Tilokchan

 12
Author: Irengbam Tilokchan Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-12 05:36:30
try:
      doSomething()
except Exception: 
    pass
else:
      stuffDoneIf()
      TryClauseSucceeds()

Dla twojej wiadomości klauzula else może zostać uruchomiona po wszystkich wyjątkach i będzie uruchamiana tylko wtedy, gdy kod w próbie nie spowoduje wyjątku.

 8
Author: MrChrisRodriguez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-19 22:35:58

W Pythonie obsługujemy wyjątki podobne do innych języków, ale różnica polega na pewnej różnicy w 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...
 3
Author: Deepak Kumar 'SORTED',
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-31 01:17:00

Po prostu podnieś odpowiedni wyjątek, tak jak to:

try:
     raise NameError('Joan')
 except NameError:
     print 'An exception just raised again by Joan!'
     raise
To takie proste. :)

aby uzyskać więcej informacji, przeczytaj tę dokumentację: https://docs.python.org/3.6/tutorial/errors.html

 -1
Author: MHBN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-03 20:21:21

Obsługa wyjątku w Pythonie: Jeśli masz jakiś podejrzany kod, który może wywołać wyjątek, możesz obronić swój program, umieszczając podejrzany kod w bloku try: block.

try:
    # Your statements .............
except ExceptionI:
    # Your statements.............
except ExceptionII:
    # Your statements..............
else:
   # Your statements
 -1
Author: pavuluri santhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-31 01:18:33