Chciałbym to zrobić w podobny sposób myślisz o, przy użyciu „nie przekaże” Gandalf obsługi wyjątku except Exception
to catch all non-system-exiting exceptions podczas tworzenia wyszczególnionego na czarnej liście set
wyjątków, które powinny zostać przekazane, a na końcu ponownie przebite.
Używanie Gandalf obsługi zadba GeneratorExit
, SystemExit
i KeyboardInterrupt
(wszystkie wyjątki systemowe wyjściu) przechodzi i zakończyć program, jeśli nie ma innych teleskopowe są obecne wyższe w stosie wywołań. Tutaj można sprawdzić pod numerem type(e)
, czy __class__
przechwyconego wyjątku e
rzeczywiście należy do zestawu wyjątków wymienionych na Czarnym i jest w tym przypadku ponownie.
Jako mały pokaz:
import exceptions # Py2.x only
# dictionary holding {exception_name: exception_class}
excptDict = vars(exceptions)
exceptionNames = ['MemoryError', 'OSError', 'SystemError'] # and others
# set containing black-listed exceptions
blackSet = {excptDict[exception] for exception in exceptionNames}
Teraz blackSet = {OSError, SystemError, MemoryError}
trzymając klasy non-system-wychodzenia wyjątki chcemy nie uchwytem.
try-except
blok może teraz wyglądać następująco:
try:
# calls that raise exceptions:
except Exception as e:
if type(e) in blackSet: raise e # re-raise
# else just handle it
przykład który łapie wszystkie wyjątki używając BaseException
może pomóc zilustrować, co mam na myśli. (robi się to tylko dla celów demonstracyjnych , aby zobaczyć, jak to podniesienie ostatecznie zakończy twój program).Notatka: Jestem nie sugeruje użycie BaseException
; Używam go w celu wykazać co wyjątek rzeczywiście „przejść” i spowodować Termination (czyli wszystko co BaseException
połowy):
for i, j in excptDict.iteritems():
if i.startswith('__'): continue # __doc__ and other dunders
try:
try:
raise j
except Exception as ex:
# print "Handler 'Exception' caught " + str(i)
if type(ex) in blackSet:
raise ex
except BaseException:
print "Handler 'BaseException' caught " + str(i)
# prints exceptions that would cause the system to exit
Handler 'BaseException' caught GeneratorExit
Handler 'BaseException' caught OSError
Handler 'BaseException' caught SystemExit
Handler 'BaseException' caught SystemError
Handler 'BaseException' caught KeyboardInterrupt
Handler 'BaseException' caught MemoryError
Handler 'BaseException' caught BaseException
Wreszcie, w celu uczynienia tej Python 2/3 agnostyk , możesz try
i import exceptions
, a jeśli to się nie powiedzie (co robi w Pythonie 3), powróć do importowania builtins
, która zawiera wszystkie Exceptions
; szukamy słownika nazwy więc nie ma różnicy:
try:
import exceptions
excDict = vars(exceptions)
except ImportError:
import builtins
excDict = vars(builtins)
nie wiem, czy jest lepszy sposób, aby rzeczywiście to zrobić, innym rozwiązaniem może być zamiast mieć try-except
z signle except
, mając 2 koparki, jeden na czarnej liście wyjątków i druga dla przypadku ogólnym:
try:
# calls that raise exceptions:
except tuple(blackSet) as be: # Must go first, of course.
raise be
except Exception as e:
# handle the rest
Może to również pomóc w podjęciu decyzji o tym, które z wyjątków zarządzać: Wbudowana hierarchia wyjątków: https://docs.python.org/3.5/library/exceptions.html#exception-hierarchy – Timur