
In Python werden try undexcept used, um Ausnahmen (=während der Ausführung erkannte Fehler) zu behandeln. Mit Versuch und Ausnahme WIRD der Prozess normalerweise, ohne dass er WIRD, Selbst Wenn Eine Ausnahme auftritt. Sie can else und final verwenden, um den Endvorgang festzulegen.
Dieser Artikel hat folgenden Inhalt.
- Grundlegende Ausnahmebehandlung in Python:
try ... except ...
- Fangen Sie mehrere Ausnahmen ab
- Wenden Sie verschiedene Operationen auf mehrere Ausnahmen an
- Wenden Sie diesen Vorgang auf mehrere Ausnahmen an
- Fangen Sie alle Ausnahmen ab
- Wildcard außer (Bloß außer)
- Basisklasse:
Exception
- Aktion ausführen, wenn keine Ausnahme:
try ... except ... else ...
- Aufräumaktion:
try ... except ... finally ...
- Ausnahmen ignoriert:
pass
- Praxisbeispiel: Bilddateien einlesen
Grundlegende Ausnahmebehandlung in Python:try ... except ...
Wenn beispielsweise versucht wird, durch Null zu dividieren, wird ZeroDivisionError ausgelöst und der Prozess endet.
# print(1 / 0)
# ZeroDivisionError: division by zero
Um diese Ausnahme abzufangen, schreiben Sie wie folgt:
try:
print(1 / 0)
except ZeroDivisionError:
print('Error')
# Error
Durch Setzen von außer als : WIRD das Ausnahmeobjekt in der Variablen gespeichert. Sie können einen beliebigen Namen für die Variable angeben, aber Namen wie e und err werden oft verwendet.
DasObjekt Ausnahme enthält Fehlermeldungen, sterben ausgegeben Werden, Wenn Eine Ausnahme auftritt, und SIE can sterben Details des Fehlers überprüfen, Indem Sie es ausgeben.
try:
print(1 / 0)
except ZeroDivisionError as e:
print(e)
print(type(e))
# division by zero
# <class 'ZeroDivisionError'>
In Python2 sollten Sie außer ,: schreiben.
Sie können auch eine Basisklasse angeben. Beispiel ist ArithmeticError sterben Basisklasse für ZeroDivisionError. Die Variable speichert das tatsächlich aufgetretene Ausnahmeobjekt der abgeleiteten Klasse.
print(issubclass(ZeroDivisionError, ArithmeticError))
# True
try:
print(1 / 0)
except ArithmeticError as e:
print(e)
print(type(e))
# division by zero
# <class 'ZeroDivisionError'>
Informationen zu integrierten Ausnahmen in Python finden Sie in der offiziellen Dokumentation.
Wenn in der try-Klausel eine Ausnahme auftritt, wird der nachfolgende Prozess in der try-Klausel übersprungen.
Wie im following Beispiel gezeigt, endet die For-Schleife an diesem Punkt, Wenn Eine Ausnahme in der Mitte der For-Schleife auftritt, und der Prozess in der Except-Klausel ausgeführt wird.
try:
for i in [-2, -1, 0, 1, 2]:
print(1 / i)
except ZeroDivisionError as e:
print(e)
# -0.5
# -1.0
# division by zero
SIE können den auszuführenden Prozess nach der Exception-Klausel in der späteren Else- und Final-Klausel angeben.
Fangen Sie mehrere Ausnahmen ab
Definieren Sie die folgende Funktion, die ZeroDivisionError abfängt.
def divide(a, b):
try:
print(a / b)
except ZeroDivisionError as e:
print('catch ZeroDivisionError:', e)
Mit dieser Funktion kann ZeroDivisionError abgefangen werden, aber andere Ausnahmen können nicht abgefangen werden.
divide(1, 0)
# catch ZeroDivisionError: division by zero
# divide('a', 'b')
# TypeError: unsupported operand type(s) for /: 'str' and 'str'
Wenden Sie verschiedene Operationen auf mehrere Ausnahmen an
SIE können mehrere Exception-Klauseln angeben und unterschiedliche Operationen für JEDE Ausnahme festlegen.
def divide_each(a, b):
try:
print(a / b)
except ZeroDivisionError as e:
print('catch ZeroDivisionError:', e)
except TypeError as e:
print('catch TypeError:', e)
divide_each(1, 0)
# catch ZeroDivisionError: division by zero
divide_each('a', 'b')
# catch TypeError: unsupported operand type(s) for /: 'str' and 'str'
Wenden Sie diesen Vorgang auf mehrere Ausnahmen an
Sie können mehrere Ausnahmenamen als Tupel in einer Ausnahme-Klausel angeben.
def divide_same(a, b):
try:
print(a / b)
except (ZeroDivisionError, TypeError) as e:
print(e)
divide_same(1, 0)
# division by zero
divide_same('a', 'b')
# unsupported operand type(s) for /: 'str' and 'str'
Fangen Sie alle Ausnahmen ab
Es ist auch möglich, alle Ausnahmen abzufangen, ohne Ausnahmen anzugeben.
Wildcard außer (Bloß außer)
Alle Ausnahmen can abgefangen Werden, Indem der Name der Ausnahme in der Exception-Klausel weggelassen WIRD. Wenn es mehrere Ausnahmeklauseln gibt, kann der Ausnahmename nur in der letzten Ausnahmeklausel weggelassen werden.
Die Except-Klausel ohne Ausnahmenamen heißt Wildcard-Except, Bare-Except usw. Achten Sie darauf, sie so zu verwenden, wie es in der offiziellen Dokumentation beschrieben ist.
In der letzten Ausnahmeklausel können die Ausnahmenamen weggelassen Werden, um als Platzhalter zu dienen. Verwenden Sie dies mit äußerster Vorsicht, da auf diese Weise leicht ein echter Programmierfehler verschleiert werden kann!
8. Fehler und Ausnahmen – Behandlung von Ausnahmen – Dokumentation zu Python 3.9.0
def divide_wildcard(a, b):
try:
print(a / b)
except:
print('Error')
divide_wildcard(1, 0)
# Error
divide_wildcard('a', 'b')
# Error
Mit Platzhalter außer Werden alle Ausnahmen einschließlich SystemExit (ausgelöst durch sys.exit() usw.) und KeyboardInterrupt (ausgelöst durch Eingabe der Unterbrechungstaste Strg + C) abgefangen. In vielen Fällen ist es besser, den Prozess zu beenden, ohne diese Ausnahmen abzufangen, daher ist es besser, die als nächste beschriebene Ausnahme zu verwenden.
Basisklasse:Exception
SIE can Exception in der Except-Klausel angeben, sterben die Basisklasse für alle eingebauten Ausnahmen ist, sterben das System nicht verlassen.
def divide_exception(a, b):
try:
print(a / b)
except Exception as e:
print(e)
divide_exception(1, 0)
# division by zero
divide_exception('a', 'b')
# unsupported operand type(s) for /: 'str' and 'str'
Die Klassenhierarchie für eingebaute Ausnahmen ist wie folgt.
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ...
...
Da SystemExit und KeyboardInterrupt Exception nicht erben, werden sys.exit() und die Ausnahme der Interrupt-Tasteneingabe nicht abgefangen, wenn Exception in der Except-Klausel angegeben ist.
Diese Ausnahme wird von der Funktion sys.exit() ausgelöst. Es erbt von BaseException anstelle von Exception, sodass es nicht von Code abgefangen wird, der Exception abfängt. Dadurch kann sich die Ausnahme regelmäßig nach oben ausbreiten und den Interpreter zum Beenden überwachen.
Eingebaute Ausnahmen – SystemExit – Dokumentation zu Python 3.9.0
Wird ausgelöst, wenn der Benutzer die Unterbrechungstaste ausdrückt (normalerweise Control-C oder Delete). Während der Ausführung WIRD regelmäßig auf Interrupts geprüft. Die Ausnahme erbt von BaseException, damit sie nicht von Code abgefangen WIRD, der Exception abfängt, und somit verhindert, dass der Interpreter beendet WIRD.
Eingebaute Ausnahmen – KeyboardInterrupt – Dokumentation zu Python 3.9.0
Die Basisklasse für alle eingebauten Ausnahmen, einschließlich SystemExit und KeyboardInterrupt, isBaseException. Wenn SIE in der Except-Klausel BaseException anstelle von Exception angeben, werden alle Ausnahmen sowie Wildcard-Ausnahmen abgefangen.
Es ist besser, die erwarteten Ausnahmen so weit wie möglich in der Except-Klausel anzugeben, da das Abfangen selbst einer unerwarteten Ausnahme einen Fehler verursachen kann.
Aktion ausführen, wenn keine Ausnahme:try ... except ... else ...
Sie können die Ausführungde Aktion angeben, wenn es keine Ausnahme in der Else-Klausel gibt. Wenn eine Ausnahme auftritt und von except abgefangen WIRD, WIRD die Aktion in der else-Klausel nicht ausgeführt.
def divide_else(a, b):
try:
print(a / b)
except ZeroDivisionError as e:
print('catch ZeroDivisionError:', e)
else:
print('finish (no error)')
divide_else(1, 2)
# 0.5
# finish (no error)
divide_else(1, 0)
# catch ZeroDivisionError: division by zero
Aufräumaktion:try ... except ... finally ...
In der final-Klausel können Sie die Bereinigungsaktion angeben, die ausgeführt werden soll, unabhängig davon, ob eine Ausnahme auftritt oder nicht.
def divide_finally(a, b):
try:
print(a / b)
except ZeroDivisionError as e:
print('catch ZeroDivisionError:', e)
finally:
print('all finish')
divide_finally(1, 2)
# 0.5
# all finish
divide_finally(1, 0)
# catch ZeroDivisionError: division by zero
# all finish
SIE can also sterben else- und final-Klausel zusammen verwenden. Wenn keine Ausnahme auftritt, wird die Else-Klausel ausgeführt und anschließend die Final-Klausel ausgeführt.
def divide_else_finally(a, b):
try:
print(a / b)
except ZeroDivisionError as e:
print('catch ZeroDivisionError:', e)
else:
print('finish (no error)')
finally:
print('all finish')
divide_else_finally(1, 2)
# 0.5
# finish (no error)
# all finish
divide_else_finally(1, 0)
# catch ZeroDivisionError: division by zero
# all finish
Ausnahmen ignoriert:pass
Wenn Sie eine Ausnahme abfangen und ohne etwas tun möchten, verwenden Sie pass.
def divide_pass(a, b):
try:
print(a / b)
except ZeroDivisionError:
pass
divide_pass(1, 0)
Notebooks zur Pass-Anweisung FINDEN SIE IMFOLGENDEN ARTIKEL.
Praxisbeispiel: Bilddateien einlesen
Ein praktisches Beispiel für die Verwendung der Ausnahmebehandlung ist das Lesen von Bilddateien.
Im Folgenden finden Sie ein Beispiel für die Größenänderung der Bilddateien im Ordner mit Kissen.
Ohne Ausnahmebehandlung:
Rufen Sie alle Dateipfade im Ordner mit glob() ab und ändern Sie die Größe nur von Dateien, die bestimmten Erweiterungen entsprechen.
import os
import glob
from PIL import Image
dst_dir = 'data/temp/images_half'
os.makedirs(dst_dir, exist_ok=True)
files = glob.glob('./data/temp/images/*')
for f in files:
root, ext = os.path.splitext(f)
if ext in ['.jpg', '.png']:
img = Image.open(f)
img_resize = img.resize((img.width // 2, img.height // 2))
basename = os.path.basename(root)
img_resize.save(os.path.join(dst_dir, basename + '_half' + ext))
Da Bilddateien verschiedene Erweiterungen haben, ist es schwierig, alle anzugeben.
Mit Ausnahmebehandlung:
files = glob.glob('./data/temp/images/*')
for f in files:
try:
img = Image.open(f)
img_resize = img.resize((img.width // 2, img.height // 2))
root, ext = os.path.splitext(f)
basename = os.path.basename(root)
img_resize.save(os.path.join(dst_dir, basename + '_half' + ext))
except OSError as e:
pass
Alle Dateien, die mit Image.open() von Pillow geöffnet werden können, werden in der Größe angepasst.
Der Stil, der die Bedingung explizit wie der erste aufgestellte, heißt „LBYL: Look Before You Leap“, und der Stil, der die Ausnahmebehandlung wie der letztere verwendet, heißt „EAFP: Easier to Ask for Forgiveness than Permission“.
Beide haben Vor- und Nachteile, aber der Prozess, der viele Bedingungen benötigt, kann anhand der Ausnahmebehandlung kurz und bündig geschrieben werden.