Kiedy powinienem podklasować wyjątek w Pythonie?

10

W moim kodzie jest około siedmiu miejsc, w których zgłaszam wyjątek. Wszystkie te wyjątki są traktowane tak samo: wydrukuj błąd do pliku dziennika, przywróć domyślny stan oprogramowania i zakończ.

Podczas przeglądu kodu mój starszy inżynier, którego bardzo cenię, powiedział, że powinienem podklasować wszystkie te wyjątki. Jego argumentem jest to, że w przyszłości możemy chcieć traktować wyjątki inaczej i będzie to łatwiejsze.

Moim argumentem jest to, że obecnie zaśmieci on tylko nasz kod, a ponieważ nie wiemy, czy kiedykolwiek będziemy obchodzić się z wyjątkami inaczej, powinniśmy zostawić kod zwięzły i, jeśli i kiedy nadejdzie czas, wtedy i tylko wtedy powinniśmy podtyp .

Chciałbym usłyszeć każdy argument w każdej sprawie.

Ezdrasz
źródło
2
YAGNI ... Nie potrzebujesz go teraz i zawsze możesz go później dodać bez większych trudności.
Robert Harvey
Czy masz jakieś przykłady? Czy tylko wywołujesz Exception, na przykład, czy bardziej szczegółowe błędy wbudowane?
jonrsharpe
właśnie podnosząc wyjątek („szczegółowy opis”)
Ezra,
@Ezra przynajmniej powinieneś sprawdzić, czy istnieje bardziej odpowiedni wbudowany wyjątek (zobacz docs.python.org/2/library/exceptions.html ).
jonrsharpe

Odpowiedzi:

8

Masz rację

Argument za twoją stroną jest już wspomniany przez Roberta Harveya: nie dodawaj niepotrzebnego teraz kodu, zwłaszcza, że ​​łatwo go później dodać.

Twój recenzent też ma rację

Z drugiej strony punkt recenzenta jest również zrozumiały:

  • Zwracanie kodu generycznego Exception()nie jest zbyt pomocne dla osoby dzwoniącej: chociaż opis wyjątku wskazuje człowiekowi, co się dzieje, leczenie wyjątków inaczej programowo może być niemożliwe. Deweloper używający Twojego kodu może niechętnie zmieniać rodzaje wyjątków , w tym ze strachu (uzasadnionego lub nie) przed zniszczeniem czegoś.

    Pamiętaj, że dodanie niestandardowych wyjątków w tej chwili nie jest takie trudne :

    class MyCustomException(Exception):
        pass

    to wszystko czego potrzebujesz. To tylko dwa wiersze kodu (biorąc pod uwagę, że nie musisz nawet tworzyć osobnego pliku, jeśli umieścisz niestandardowe wyjątki w jednym pliku).

  • Sam kod wygląda lepiej, jest bardziej czytelny.

    if price < self.PriceMinValue:
        raise OutOfRangeException("The price is inferior to zero.")

    wygląda nieco bardziej czytelnie w porównaniu do:

    if price < self.PriceMinValue:
        raise Exception("The price is inferior to zero.")

    ze względu na wskazanie rodzaju wyjątku:

    • W drugim fragmencie kodu muszę przeczytać opis i zgadnąć, że cena jest poza zakresem (a może nie? Może są przypadki, w których cena może być ujemna, np. Rabaty?)

    • W pierwszym fragmencie kodu rzut oka na typ daje natychmiastową informację o błędzie. Wygląda na to, że istnieje zestaw dozwolonych wartości ceny, a bieżąca wartość jest poza tym zestawem.

Więc?

Więc:

  • Oba podejścia są prawidłowe. Jeśli nie podklasujesz wyjątków, kiedy nie potrzebujesz niestandardowych typów, masz rację. Kiedy wykonujesz podklasę wyjątków, ponieważ nic nie kosztuje, a może być przydatne później, masz rację.

  • Bądź spójny ze swoim zespołem. Jeśli Twój zespół intensywnie korzysta z wyjątków niestandardowych, skorzystaj z nich.

Arseni Mourzenko
źródło
2
Ale istnieje złoty środek: raise ValueError('The price is less than zero'). Jest to bardziej szczegółowe niż baza Exception, ale bez żadnych problemów.
jonrsharpe
+1 za proste stwierdzenie „bądź konsekwentny”, z zespołem, jeśli go masz, ze sobą, jeśli go nie masz.
Styne666,