If vs wyjątek

1

Która część kodu jest prawidłowa, górna czy dolna? Pomińmy ewentualny błąd przy konwersji inputa na inta.

a = int(input('Podaj a: '))
b = int(input('Podaj b: '))

if b == 0:
  print('Nie można dzielić przez 0')
else:
  wynik = a / b
  print(wynik)

#######################################

try:
  wynik = a / b
  print(wynik)
except ZeroDivisionError:
  print('Nie można dzielić przez 0')
2

Zacznij od zdefiniowania „prawidłowa”… Obie stanowią poprawny kod Pythona i obie są funkcjonalnie nader zbliżone, podobnie ich czytelność jest właściwie taka sama… Jakie masz kryteria decyzyjne zatem?

3

try except, zwłaszcza gdy będzie mało zer, jest szybsze, jeśli nie Masz innych kryteriów.

2

Ja bym sugerował się analogicznym podejściem jak przy słownikach : https://devblogs.microsoft.com/python/idiomatic-python-eafp-versus-lbyl/

5

PEP8 zaleca 4 spacje, a nie dwie.

Dla pierwszego przykładu, zwykle zamiast porównania b == 0 wykorzystuje się, że zerowe wartości są Falsy z konstrukcją not b

if not b:
    wynik = 'Nie można dzielić przez 0'
else:
    wynik = a / b
print(wynik)

Lub krócej, odwracając logiczność warunku

if b:
    wynik = a / b
else:
    wynik = 'Nie można dzielić przez 0'
print(wynik)

Jak ktoś chce być zwięzły, to można to skrócić do dwóch linijek wykorzystując zapis x = ... if ... else ...:

wynik = a / b if b else "Nie można dzielić przez zero"
print(wynik)

W drugim przykładzie można wyjąć print z bloku try, gdyż nigdy nie rzuci on ZeroDivisionError:

try:
    wynik = a / b
except ZeroDivisionError:
    wynik = 'Nie można dzielić przez 0'
print(wynik)

Co do preferencji (#1 vs #2) niby zaleca się wyjątki (EAFP vs LBYL), ale nie jest to dogmatyczne i oba podejścia są tak samo przyjmowane. Rozwiązanie z wyjątkami będzie pewnie nawet częściej odrzucane, ponieważ łatwiej napisać prosty test na niż wstawiać cały blok razem z długą nazwą wyjątku.

1

Moim zdaniem obie wersje są poprawne, ale normalne sterowanie w programie bardziej praktykuje się za pomocą if. W tym przypadku jest to walidacja danych wejściowych i jest to całkiem normalne, że użytkownik poda 0 jako dzielnik. Swego czasu czytałem o C# i .NET, że przy takim rozważaniu lepiej użyć if zamiast try.

Obie wersje są rónoważne, jednak odwzorowują inny sposób sterowania:

  1. Jeżeli B <> 0 to oblicz, w przeciwnym wypadku daj komunikat.
  2. Spróbuj podzielić A/B bez sprawdzania wartości B, ewentualnie, jak wyjdzie dzielenie przez 0 to daj komunikat.
3

Wyjątki są od sytuacji wyjlątkowych, takich które ciężko przewidzieć, są mało prawdopodobne i zwykle nie da się ich za bardzo "uratować". Np. jakieś out of memory.

0

Ja bym się upierał, że właśnie out of memory to jeden z gorszych przykładów na wyjątek: błędy sieci, dysku, takie rzeczy — co innego — ale sam brak pamięci zazwyczaj jest właśnie kompletnie nie do uratowania, bo co do zasady ratowanie też potrzebuje pamięci… Więc zazwyczaj tak czy owak w tej sytuacji nam się całość wyłoży na twarz.

4

Obie są poprawne, ale w Pythonie zalecane jest zwykle zasada EAFP: https://devblogs.microsoft.com/python/idiomatic-python-eafp-versus-lbyl/

Bo w Pythonie ta wersja z ifem sprawdza czy b jest zerem dwukrotnie: raz w ifie, a raz w dzieleniu...

1 użytkowników online, w tym zalogowanych: 0, gości: 1