Warum ist "except: pass" eine schlechte Programmierpraxis?
Warum ist das schlecht?
try:
something
except:
pass
Dies erfasst jede mögliche Ausnahme, einschließlich GeneratorExit
, KeyboardInterrupt
und SystemExit
- Ausnahmen, die Sie wahrscheinlich nicht beabsichtigen zu erfassen. Es ist das Gleiche wie das Fangen von BaseException
.
try:
something
except BaseException:
pass
Ältere Versionen der Dokumentation sagen:
Da in Python jeder Fehler eine Ausnahme auslöst, kann die Verwendung von except:
viele Programmfehler wie Laufzeitprobleme aussehen lassen, was den Debugging-Prozess behindert.
Python Ausnahme Hierarchie
Wenn Sie eine übergeordnete Ausnahmeklasse abfangen, fangen Sie auch alle ihre Unterklassen ab. Es ist viel eleganter, nur die Ausnahmen abzufangen, für die Sie vorbereitet sind.
Hier ist die Python 3 Ausnahme-Hierarchie - wollen Sie wirklich alle einfangen?:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
+-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
Das hier nicht tun
Wenn Sie diese Form des Exception-Handlings verwenden:
try:
something
except: # fangen Sie nicht einfach alles ab!
pass
Dann können Sie Ihren something
Block nicht mit Strg-C unterbrechen. Ihr Programm wird jede mögliche Ausnahme im try
Codeblock übersehen.
Hier ist ein weiteres Beispiel, das das gleiche unerwünschte Verhalten haben wird:
except BaseException as e: # machen Sie das auch nicht - dasselbe wie oben!
logging.info(e)
Versuchen Sie stattdessen, nur die spezifische Ausnahme abzufangen, von der Sie wissen, dass Sie sie suchen. Wenn Sie beispielsweise wissen, dass Sie möglicherweise einen Wertefehler bei einer Konvertierung erhalten:
try:
foo = operation_that_includes_int(foo)
except ValueError as e:
if fatal_condition(): # Sie können die Ausnahme auslösen, wenn sie schlecht ist,
logging.info(e) # aber wenn es jedes Mal fatal ist,
raise # sollten Sie es wahrscheinlich einfach nicht abfangen.
else: # Fange nur die Ausnahmen ab, für die du vorbereitet bist.
foo = 0 # Hier weisen wir einfach foo den Wert 0 zu und fahren fort.
Weitere Erklärung mit einem anderen Beispiel
Sie könnten dies tun, weil Sie zum Beispiel beim Web-Scraping einen UnicodeError
erhalten haben, aber weil Sie das breiteste Ausnahmefangen verwendet haben, wird Ihr Code, der möglicherweise andere grundlegende Fehler hat, versuchen, bis zum Abschluss ausgeführt zu werden, wodurch Bandbreite verschwendet wird, Bearbeitungszeit, Verschleiß an Ihrer Ausrüstung, Speicherplatz, Sammeln von falschen Daten, usw.
Wenn andere Personen von Ihnen verlangen, dass Sie abschließen, damit sie sich auf Ihren Code verlassen können, verstehe ich, dass Sie sich verpflichtet fühlen könnten, einfach alles zu behandeln. Aber wenn Sie bereit sind, während der Entwicklung laut zu scheitern, haben Sie die Möglichkeit, Probleme zu korrigieren, die möglicherweise nur gelegentlich auftreten, aber langfristig kostspielige Fehler wären.
Mit präziserer Fehlerbehandlung kann Ihr Code robuster sein.