Sie hören oft, dass Python den EAFP- Stil ("es ist einfacher, um Vergebung als um Erlaubnis zu bitten") gegenüber dem LBYL- Stil ("schauen, bevor Sie springen") fördert . Für mich ist es eine Frage der Effizienz und Lesbarkeit.
In Ihrem Beispiel (sagen wir, anstatt eine Liste oder eine leere Zeichenfolge zurückzugeben, sollte die Funktion eine Liste zurückgeben oder None) würde resultich den try/exceptAnsatz verwenden , wenn Sie erwarten, dass 99% der Zeit tatsächlich etwas Iterierbares enthalten . Es wird schneller sein, wenn Ausnahmen wirklich außergewöhnlich sind. Wenn resultist Nonemehr als 50% der Zeit, dann verwenden ifist wahrscheinlich besser.
Um dies mit ein paar Messungen zu unterstützen:
>>> import timeit
>>> timeit.timeit(setup="a=1;b=1", stmt="a/b") # no error checking
0.06379691968322732
>>> timeit.timeit(setup="a=1;b=1", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.0829463709378615
>>> timeit.timeit(setup="a=1;b=0", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.5070195056614466
>>> timeit.timeit(setup="a=1;b=1", stmt="if b!=0:\n a/b")
0.11940114974277094
>>> timeit.timeit(setup="a=1;b=0", stmt="if b!=0:\n a/b")
0.051202772912802175
Während eine ifAnweisung Sie immer kostet, ist es fast kostenlos, einen try/exceptBlock einzurichten . Aber wenn Exceptiontatsächlich ein auftritt, sind die Kosten viel höher.
Moral:
- Es ist vollkommen in Ordnung (und "pythonisch"), es
try/exceptfür die Flusskontrolle zu verwenden.
- aber es macht am meisten Sinn, wenn
Exceptions tatsächlich außergewöhnlich sind.
Aus den Python-Dokumenten:
EAFP
Es ist einfacher, um Vergebung zu bitten als um Erlaubnis. Dieser übliche Python-Codierungsstil setzt die Existenz gültiger Schlüssel oder Attribute voraus und fängt Ausnahmen ab, wenn sich die Annahme als falsch herausstellt. Dieser klare und schnelle Stil zeichnet sich durch das Vorhandensein vieler
tryund exceptAussagen aus. Die Technik steht im Gegensatz zum LBYL-
Stil, der vielen anderen Sprachen wie C gemeinsam ist.