Często słyszysz, że Python zachęca stylu EAFP („łatwiej jest prosić o przebaczenie niż o pozwolenie”) zamiast stylu LBYL („spójrz, zanim skoczysz ”). Dla mnie to kwestia wydajności i czytelności.
W twoim przykładzie (powiedz, że zamiast zwracać listę lub pusty ciąg, funkcja miała zwrócić listę lub None), jeśli spodziewasz się, że 99% czasu resultfaktycznie będzie zawierało coś iterowalnego, zastosowałbym try/exceptpodejście. Będzie szybciej, jeśli wyjątki są naprawdę wyjątkowe. Jeśli resultjest to Nonewięcej niż 50% czasu, użycie ifjest prawdopodobnie lepsze.
Aby wesprzeć to kilkoma pomiarami:
>>> 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
Tak więc, podczas gdy ifwyciąg zawsze kosztuje, skonfigurowanie try/exceptbloku jest prawie darmowe . Ale kiedy Exceptionfaktycznie nastąpi, koszt jest znacznie wyższy.
Morał:
- Jest całkowicie OK (i „pythonowy”) w użyciu
try/exceptdo sterowania przepływem,
- ale ma to sens najbardziej, gdy
Exceptionsą naprawdę wyjątkowe.
Z dokumentacji Pythona:
EAFP
Łatwiej prosić o przebaczenie niż o pozwolenie. Ten wspólny styl kodowania w Pythonie zakłada istnienie prawidłowych kluczy lub atrybutów i wyłapuje wyjątki, jeśli założenie okaże się fałszywe. Ten czysty i szybki styl charakteryzuje się obecnością wielu
tryi exceptwypowiedzi. Technika kontrastuje ze
stylem LBYL wspólnym dla wielu innych języków, takich jak C.