Sprawdź obsługę pierwszej kontra wyjątku?

88

Pracuję nad książką „Head First Python” (to jest mój język do nauki w tym roku) i doszedłem do sekcji, w której dyskutują o dwóch technikach kodu:
Sprawdzanie obsługi First vs. Exception.

Oto przykład kodu Python:

# Checking First
for eachLine in open("../../data/sketch.txt"):
    if eachLine.find(":") != -1:
        (role, lineSpoken) = eachLine.split(":",1)
        print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals())

# Exception handling        
for eachLine in open("../../data/sketch.txt"):
    try:
        (role, lineSpoken) = eachLine.split(":",1)
        print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals())
    except:
        pass

Pierwszy przykład dotyczy bezpośrednio problemu w .splitfunkcji. Drugi pozwala po prostu sobie z tym poradzić programowi obsługi wyjątków (i ignoruje problem).

W książce twierdzą, że zamiast sprawdzania najpierw używać wyjątków. Argument polega na tym, że kod wyjątku przechwytuje wszystkie błędy, przy czym sprawdzanie w pierwszej kolejności przechwytuje tylko to, o czym myślisz (i brakuje ci przypadków narożnych). Najpierw nauczono mnie sprawdzać, więc mój instynkt był taki, ale ich pomysł jest interesujący. Nigdy nie myślałem o użyciu obsługi wyjątków do załatwiania spraw.

Który z nich jest ogólnie uważany za lepszą praktykę?

jmq
źródło
12
Ta część książki nie jest mądra. Jeśli jesteś w pętli i rzucasz wyjątkami w kółko, jest to bardzo kosztowne. Próbowałem nakreślić kilka dobrych punktów, kiedy to zrobić.
Jason Sebring
9
Tylko nie wpadnij w pułapkę „sprawdzanie istnienia pliku”. Plik istnieje! = Ma dostęp do pliku lub że będzie istniał w ciągu 10 ms, aby uzyskać dostęp do mojego otwartego wywołania pliku itp. Blogs.msdn.com/b/jaredpar/archive/2009/04/27/…
Billy ONeal
11
Wyjątki są traktowane inaczej w Pythonie niż w innych językach. Na przykład sposobem na iterację w kolekcji jest wywołanie w niej .next (), dopóki nie zgłosi wyjątku.
WuHoUnited
4
@ emeraldcode.com To nie do końca prawda o Pythonie. Nie znam szczegółów, ale język został zbudowany wokół tego paradygmatu, więc zgłaszanie wyjątków nie jest tak kosztowne jak w innych językach.
Izkata,
To powiedziawszy, w tym przykładzie użyłbym polecenia straży: if -1 == eachLine.find(":"): continuewtedy reszta pętli również nie byłaby wcięta.
Izkata,

Odpowiedzi:

68

W .NET powszechną praktyką jest unikanie nadużywania wyjątków. Jednym argumentem jest wydajność: w .NET zgłoszenie wyjątku jest drogie obliczeniowo.

Innym powodem, dla którego należy unikać ich nadużywania, jest to, że bardzo trudno jest odczytać kod, który zbytnio na nich polega. Wpis na blogu Joela Spolsky'ego dobrze opisuje problem.

Sednem argumentu jest następujący cytat:

Powodem jest to, że uważam wyjątki za nie lepsze niż „goto”, uważane za szkodliwe od lat 60. XX wieku, ponieważ powodują one gwałtowny skok z jednego punktu kodu do drugiego. W rzeczywistości są znacznie gorsze niż goto:

1. Są niewidoczne w kodzie źródłowym . Patrząc na blok kodu, w tym funkcje, które mogą generować wyjątki, ale nie ma sposobu, aby zobaczyć, które wyjątki mogą zostać zgłoszone i skąd. Oznacza to, że nawet staranna kontrola kodu nie ujawnia potencjalnych błędów.

2. Tworzą zbyt wiele możliwych punktów wyjścia dla funkcji. Aby napisać poprawny kod, naprawdę musisz pomyśleć o każdej możliwej ścieżce kodu w swojej funkcji. Za każdym razem, gdy wywołujesz funkcję, która może zgłosić wyjątek i nie złapać go na miejscu, stwarzasz możliwości niespodziewanych błędów spowodowanych przez funkcje, które nagle się zakończyły, pozostawiając dane w niespójnym stanie lub inne ścieżki kodu, których nie myśleć o.

Osobiście zgłaszam wyjątki, gdy mój kod nie może robić tego, co jest zlecone. Zwykle używam try / catch, gdy mam zamiar poradzić sobie z czymś poza granicami mojego procesu, na przykład wywołaniem SOAP, wywołaniem bazy danych, wywołaniem pliku lub wywołaniem systemowym. W przeciwnym razie próbuję kodować defensywnie. Nie jest to trudna i szybka reguła, ale jest to ogólna praktyka.

Scott Hanselman pisze tutaj także o wyjątkach w .NET . W tym artykule opisuje kilka praktycznych zasad dotyczących wyjątków. Mój ulubiony?

Nie powinieneś rzucać wyjątków od rzeczy, które zdarzają się cały czas. Wtedy byliby „zwykłymi”.

Kyle Hodgson
źródło
5
oto kolejny punkt: jeśli rejestrowanie wyjątków jest włączone w całej aplikacji, lepiej jest używać wyjątku tylko w wyjątkowych warunkach, a nie w przypadku zamówień zwykłych. W przeciwnym razie dziennik zostanie zaśmiecony, a rzeczywiste przyczyny powodujące błędy zostaną ukryte.
rwong
2
Niezła odpowiedź. Należy jednak pamiętać, że wyjątki mają wysoką wydajność na większości platform. Jednak, jak zauważyliście w moich komentarzach do innych odpowiedzi, wydajność nie jest brana pod uwagę w przypadku decydowania o ogólnej zasadzie, jak coś skodyfikować.
mattnz
1
Cytat Scotta Hanselmana lepiej opisuje stosunek .Net do wyjątków niż „nadużywanie”. Często wspomina się o wydajności, ale prawdziwym argumentem jest odwrotność tego, dlaczego POWINNO używać wyjątków - sprawia, że ​​kod jest trudniejszy do zrozumienia i radzenia sobie, gdy zwykły warunek powoduje wyjątek. Jeśli chodzi o Joela, punkt 1 jest w rzeczywistości dodatni (niewidoczny oznacza, że ​​kod pokazuje, co robi, a nie to, czego nie robi), a punkt 2 nie ma znaczenia (jesteś już w niespójnym stanie lub nie powinno być wyjątku) . Mimo to +1 za „nie można zrobić, o co go poproszono”.
jmoreno
5
Chociaż ta odpowiedź jest dobra dla .Net, nie jest bardzo pytoniczna , więc biorąc pod uwagę, że jest to pytanie pythonowe, nie rozumiem, dlaczego odpowiedź Ivc nie została poddana większemu głosowaniu.
Mark Booth
2
@IanGoldby: nie. Obsługa wyjątków jest właściwie lepiej opisana jako odzyskiwanie wyjątków. Jeśli nie możesz odzyskać od wyjątku, prawdopodobnie nie powinieneś mieć żadnego kodu obsługi wyjątku. Jeśli metoda A wywołuje metodę B, która wywołuje C, a C rzuca, najprawdopodobniej EITHER A OR B powinien się zregenerować, a nie jedno i drugie. Należy unikać decyzji „jeśli nie mogę zrobić X, zrobię Y”, jeśli Y wymaga, aby ktoś wykonał zadanie. Jeśli nie możesz ukończyć zadania, pozostaje tylko czyszczenie i logowanie. Czyszczenie w .net powinno być automatyczne, rejestrowanie powinno być scentralizowane.
jmoreno
78

W szczególności w Pythonie zwykle uważa się, że lepszą praktyką jest złapanie wyjątku. Zwykle nazywa się go Łatwiej prosić o przebaczenie niż pozwolenie (EAFP), w porównaniu do Look Before You Leap (LBYL). Są przypadki, w których LBYL da ci subtelne błędy w niektórych przypadkach.

Jednak należy być ostrożnym z gołymi except:sprawozdania , jak również zbyt szeroko wyjątkiem sprawozdania, ponieważ mogą one również maskować błędy zarówno - coś takiego byłoby lepiej:

for eachLine in open("../../data/sketch.txt"):
    try:
        role, lineSpoken = eachLine.split(":",1)
    except ValueError:
        pass
    else:
        print("role=%(role)s lineSpoken=%(lineSpoken)s" % locals())
lvc
źródło
8
Jako programista .NET kulę się z tym. Ale z drugiej strony wy ludzie robicie wszystko dziwnie. :)
Phil
Jest to wyjątkowo frustrujące (gra słów nieprzeznaczona), gdy interfejsy API nie są spójne, które wyjątki są zgłaszane w jakich okolicznościach lub gdy wiele różnych rodzajów awarii jest zgłaszanych w ramach tego samego typu wyjątku.
Jack
W rezultacie używasz tego samego mechanizmu do nieoczekiwanych błędów i oczekiwanego rodzaju zwracanych wartości. To mniej więcej tak wielkie, jak użycie 0 jako liczby, fałszywego bool ORAZ niepoprawnego wskaźnika, który zakończy proces z kodem wyjściowym 128 + SIGSEGV, ponieważ jak wygodnie, nie potrzebujesz teraz różnych rzeczy. Jak spork! Lub buty z palcami u stóp ...
Yeoman
2
@yeoman kiedy rzucić wyjątek to inna kwestia, ten jest o używaniu try/ exceptzamiast konfigurowania warunkowego dla „jest następujący prawdopodobnie wyjątek”, a Python praktyką jest zdecydowanie preferują pierwsze. Nie przeszkadza to, że takie podejście jest (prawdopodobnie) bardziej wydajne, ponieważ w przypadku, gdy podział się powiedzie, chodzisz po łańcuchu tylko raz. Jeśli chodzi o to, czy splitnależy tu rzucić wyjątek, powiedziałbym, że zdecydowanie powinien - jedną powszechną zasadą jest to, że powinieneś rzucać wyjątek, gdy nie możesz zrobić tego, co mówi twoje imię i nie możesz rozdzielić przy brakującym ograniczniku.
lvc
Nie uważam tego za złe, powolne ani straszne, zwłaszcza że wychwytuje się tylko określony wyjątek. Ans Naprawdę lubię Python. To po prostu zabawne, że czasami nie pokazuje żadnego smaku, jak powiedział C użycie cyfry zero, Spork i ulubione buty Randall Munroe z palcami u stóp :) Plus, kiedy jestem w Pythonie i API mówi, że to jest sposób, aby to zrobić, pójdę po to :) Sprawdzanie z góry warunków oczywiście nigdy nie jest dobrym pomysłem ze względu na współbieżność, coroutines lub jeden z tych, które są dodawane później ...
yeoman
27

Podejście pragmatyczne

Powinieneś być defensywny, ale do pewnego stopnia. Powinieneś napisać obsługę wyjątków, ale do pewnego stopnia. Będę używał programowania internetowego jako przykładu, ponieważ tutaj mieszkam.

  1. Załóż, że wszystkie dane wejściowe użytkownika są nieprawidłowe i pisz obronnie tylko do punktu weryfikacji typu danych, kontroli wzorca i złośliwego wstrzyknięcia. Programowanie defensywne powinno być rzeczą, która może się zdarzyć bardzo często, a której nie można kontrolować.
  2. Napisz obsługę wyjątków dla usług sieciowych, które mogą czasami zawieść i z wdzięcznością obsługuj opinie użytkowników. Programowania wyjątków należy używać do rzeczy sieciowych, które od czasu do czasu mogą zawieść, ale zwykle są solidne ORAZ musisz utrzymać program w działaniu.
  3. Nie zawracaj sobie głowy pisaniem obronnym w aplikacji po sprawdzeniu poprawności danych wejściowych. Jest to strata czasu i wzdęcia Twojej aplikacji. Niech wybuchnie, ponieważ albo jest to coś bardzo rzadkiego, co nie jest warte obsługi, albo oznacza, że ​​musisz uważniej przyjrzeć się krokom 1 i 2.
  4. Nigdy nie pisz obsługi wyjątków w kodzie podstawowym, który nie jest zależny od urządzenia sieciowego. Takie postępowanie jest złe programowanie i kosztowne dla wydajności. Na przykład napisanie try-catch w przypadku poza zakresem tablicy w pętli oznacza, że ​​nie zaprogramowałeś poprawnie pętli w pierwszej kolejności.
  5. Niech wszystko zostanie obsłużone przez centralne rejestrowanie błędów, które wychwytują wyjątki w jednym miejscu po wykonaniu powyższych procedur. Nie można złapać każdego przypadku krawędzi, ponieważ może to być nieskończone, wystarczy napisać kod, który obsługuje oczekiwaną operację. Dlatego używasz centralnej obsługi błędów w ostateczności.
  6. TDD jest fajny, ponieważ w pewnym sensie próbuje cię złapać bez wzdęć, co oznacza, że ​​daje pewną pewność normalnej pracy.
  7. Punkty bonusowe to użycie narzędzia do pokrycia kodu, na przykład Stambuł jest dobrym narzędziem dla węzła, ponieważ pokazuje, gdzie nie testujesz.
  8. Zastrzeżeniem tego wszystkiego są wyjątki przyjazne dla programistów . Na przykład, język rzuciłby się, jeśli źle użyłeś składni i wyjaśniłbyś dlaczego. Podobnie jak biblioteki narzędzi , od których zależy większość kodu.

Wynika to z doświadczenia pracy w scenariuszach dużych zespołów.

Analogia

Wyobraź sobie, że przez cały czas nosiłeś kombinezon kosmiczny w ISS. W ogóle trudno byłoby pójść do łazienki lub zjeść. Poruszanie się w module kosmicznym byłoby bardzo duże. To by było do bani. Pisanie kilku próbnych haczyków w kodzie jest trochę podobne. Musisz mieć punkt, w którym powiesz: hej, zabezpieczyłem ISS, a moi astronauci w środku są w porządku, więc po prostu nie jest praktyczne noszenie skafandra na każdy możliwy scenariusz.

Jason Sebring
źródło
4
Problem z punktem 3 polega na tym, że zakłada on program, a programiści nad nim pracujący są idealni. Nie są, więc najlepiej program obronny mieć na uwadze. Odpowiednie kwoty w kluczowym momencie mogą uczynić oprogramowanie o wiele bardziej niezawodnym niż mentalność „Jeśli sprawdzane są dane wejściowe, wszystko jest idealne”.
mattnz
po to jest testowanie.
Jason Sebring,
3
Testowanie to nie wszystko. Nie widziałem jeszcze pakietu testowego, który ma 100% kodu i „środowiskowy” zasięg.
Marjan Venema
1
@ emeraldcode: Czy chcesz ze mną pracy, chciałbym mieć kogoś w zespole, który zawsze, z wyjątkiem wyjątku, testuje każdą permutację każdego przypadku Edge, który kiedykolwiek wykona oprogramowanie. Musisz być miły, wiedząc z pewnością abosoluite, że Twój kod jest doskonale przetestowany.
mattnz
1
Zgodzić się. Istnieją scenariusze, w których zarówno programowanie defensywne, jak i obsługa wyjątków działają dobrze i źle, a my, programiści, powinniśmy nauczyć się je rozpoznawać i wybrać technikę, która najlepiej pasuje. Podoba mi się punkt 3, ponieważ uważam, że na pewnym poziomie kodu musimy założyć, że pewne warunki kontekstowe powinny zostać spełnione. Warunki te są spełnione przez defensywne kodowanie w zewnętrznej warstwie kodu i myślę, że obsługa wyjątków jest odpowiednia, gdy te założenia zostaną złamane w warstwie wewnętrznej.
yaobin,
15

Głównym argumentem tej książki jest to, że wersja wyjątkowa kodu jest lepsza, ponieważ przechwyci wszystko, co można przeoczyć, jeśli spróbujesz napisać własne sprawdzanie błędów.

Myślę, że to stwierdzenie jest prawdziwe tylko w bardzo szczególnych okolicznościach - gdy nie obchodzi cię, czy dane wyjściowe są prawidłowe.

Nie ma wątpliwości, że zgłaszanie wyjątków jest rozsądną i bezpieczną praktyką. Powinieneś to zrobić za każdym razem, gdy czujesz, że jest coś w bieżącym stanie programu, z którym (jako programista) nie możesz lub nie chcesz sobie poradzić.

Twój przykład dotyczy jednak wychwytywania wyjątków. Jeśli złapiesz wyjątek, nie chronisz się przed scenariuszami, które mogłeś przeoczyć. Robisz dokładnie odwrotnie: zakładasz, że nie przeoczyłeś żadnego scenariusza, który mógłby spowodować tego rodzaju wyjątek, i dlatego masz pewność, że można go złapać (a tym samym uniemożliwić wyjście programu, jak każdy niewyłapany wyjątek).

Używając podejścia wyjątkowego, jeśli widzisz ValueErrorwyjątek, pomijasz linię. Stosując tradycyjne podejście nie będące wyjątkami, zliczasz liczbę zwróconych wartości split, a jeśli jest mniejsza niż 2, pomijasz linię. Czy powinieneś czuć się bezpieczniej dzięki podejściu wyjątkowemu, ponieważ mogłeś zapomnieć o innych sytuacjach „błędu” w tradycyjnym sprawdzaniu błędów i except ValueErrorzłapałbyś je dla siebie?

To zależy od charakteru twojego programu.

Jeśli piszesz na przykład przeglądarkę internetową lub odtwarzacz wideo, problem z danymi wejściowymi nie powinien powodować awarii z niewyłapanym wyjątkiem. O wiele lepiej jest wydać coś sensownie (nawet jeśli, ściśle mówiąc, niepoprawnego), niż wyjść.

Jeśli piszesz aplikację, w której ważna jest poprawność (np. Oprogramowanie biznesowe lub inżynierskie), byłoby to okropne podejście. Jeśli zapomniałeś o jakimś scenariuszu, który wywołuje ValueError, najgorsze, co możesz zrobić, to po cichu zignorować ten nieznany scenariusz i po prostu pominąć linię. W ten sposób bardzo subtelne i kosztowne błędy kończą się w oprogramowaniu.

Możesz pomyśleć, że jedynym sposobem na zobaczenie ValueErrortego kodu jest splitzwrócenie tylko jednej wartości (zamiast dwóch). Ale co, jeśli twoje printoświadczenie zacznie później używać wyrażenia, które pojawia się ValueErrorw pewnych warunkach? Spowoduje to, że pominiesz niektóre linie nie dlatego, że nie trafiają :, ale dlatego, że printzawodzą. To jest przykład subtelnego błędu, o którym wspominałem wcześniej - niczego nie zauważysz, po prostu stracisz kilka linii.

Radzę, aby unikać wychwytywania (ale nie podnoszenia!) Wyjątków w kodzie, w których wytwarzanie niepoprawnych danych wyjściowych jest gorsze niż wychodzenie. Jedyny raz, kiedy wychwytuję wyjątek w takim kodzie, ma naprawdę trywialne wyrażenie, dzięki czemu mogę łatwo zrozumieć, co może powodować każdy z możliwych typów wyjątków.

Jeśli chodzi o wpływ zastosowania wyjątków na wydajność, jest to trywialne (w Pythonie), chyba że często występują wyjątki.

Jeśli używasz wyjątków do obsługi rutynowo występujących warunków, możesz w niektórych przypadkach ponieść ogromne koszty wydajności. Załóżmy na przykład, że zdalnie wykonujesz jakieś polecenie. Możesz sprawdzić, czy tekst polecenia spełnia przynajmniej minimalne wymagania sprawdzania poprawności (np. Składnia). Możesz też poczekać na zgłoszenie wyjątku (co dzieje się dopiero po zdalnym przeanalizowaniu polecenia przez zdalny serwer i znalezieniu problemu). Oczywiście ten pierwszy jest o rząd wielkości szybszy. Kolejny prosty przykład: możesz sprawdzić, czy liczba jest zero ~ 10 razy szybsza niż próba wykonania podziału, a następnie wyłapanie wyjątku ZeroDivisionError.

Te rozważania mają znaczenie tylko wtedy, gdy często wysyłasz zniekształcone ciągi poleceń do zdalnych serwerów lub otrzymujesz argumenty o zerowej wartości, których używasz do dzielenia.

Uwaga: Zakładam, że użyłbyś except ValueErrorzamiast sprawiedliwego except; jak zauważyli inni, i jak sama książka mówi na kilku stronach, nigdy nie powinieneś używać goły except.

Inna uwaga: właściwym podejściem nie będącym wyjątkiem jest policzenie liczby zwracanych wartości splitzamiast szukania :. Ten ostatni jest zdecydowanie zbyt wolny, ponieważ powtarza pracę wykonaną przez spliti może prawie podwoić czas wykonania.

max
źródło
6

Zasadniczo, jeśli wiesz, że instrukcja może wygenerować niepoprawny wynik, przetestuj ją i sobie z tym poradzić. Używaj wyjątków dla rzeczy, których nie oczekujesz; rzeczy, które są „wyjątkowe”. Sprawia, że ​​kod jest jaśniejszy w sensie umownym (na przykład „nie powinno być zerowe”).

Ian
źródło
2

Używaj tego, co zawsze działa dobrze w ...

  • wybrany język programowania pod względem czytelności kodu i wydajności
  • Twój zespół i zestaw uzgodnionych konwencji kodu

Zarówno obsługa wyjątków, jak i programowanie obronne są różnymi sposobami wyrażania tego samego zamiaru.

Sri
źródło
0

TBH, nie ma znaczenia, czy użyjesz try/exceptmechaniki czy kontroli ifwyciągów. Zazwyczaj zarówno EAFP, jak i LBYL występują w większości linii bazowych języka Python, przy czym EAFP jest nieco bardziej powszechny. Czasami EAFP jest znacznie bardziej czytelny / idiomatyczny, ale w tym konkretnym przypadku myślę, że i tak jest dobrze.

Jednak...

Będę ostrożny przy użyciu twojego aktualnego odniesienia. Kilka rażących problemów z kodem:

  1. Deskryptor pliku wyciekł. Nowoczesne wersje CPython ( specyficzny interpreter Pythona) faktycznie go zamkną, ponieważ jest to anonimowy obiekt, który ma zasięg tylko w pętli (gc nuke go po pętli). Jednak inni tłumacze nie mają tej gwarancji. Mogą natychmiast wyciec deskryptor. Prawie zawsze chcesz używać tego withidiomu podczas czytania plików w Pythonie: istnieje bardzo niewiele wyjątków. To nie jest jeden z nich.
  2. Obsługa wyjątków Pokemonów jest niezadowolona z tego, że maskuje błędy (tzn. Zwykła exceptinstrukcja, która nie przechwytuje konkretnego wyjątku)
  3. Nit: Nie potrzebujesz parenów do rozpakowywania krotek. Można po prostu zrobićrole, lineSpoken = eachLine.split(":",1)

Ivc ma dobrą odpowiedź na ten temat i EAFP, ale przecieka także deskryptor.

Wersja LBYL niekoniecznie jest tak wydajna jak wersja EAFP, więc twierdzenie, że zgłaszanie wyjątków jest „drogie pod względem wydajności”, jest kategorycznie fałszywe. To zależy od rodzaju przetwarzanych ciągów:

In [33]: def lbyl(lines):
    ...:     for line in lines:
    ...:         if line.find(":") != -1:
    ...:             # Nuke the parens, do tuple unpacking like an idiomatic Python dev.
    ...:             role, lineSpoken = line.split(":",1)
    ...:             # no print, since output is obnoxiously long with %timeit
    ...:

In [34]: def eafp(lines):
    ...:     for line in lines:
    ...:         try:
    ...:             # Nuke the parens, do tuple unpacking like an idiomatic Python dev.
    ...:             role, lineSpoken = eachLine.split(":",1)
    ...:             # no print, since output is obnoxiously long with %timeit
    ...:         except:
    ...:             pass
    ...:

In [35]: lines = ["abc:def", "onetwothree", "xyz:hij"]

In [36]: %timeit lbyl(lines)
100000 loops, best of 3: 1.96 µs per loop

In [37]: %timeit eafp(lines)
100000 loops, best of 3: 4.02 µs per loop

In [38]: lines = ["a"*100000 + ":" + "b", "onetwothree", "abconetwothree"*100]

In [39]: %timeit lbyl(lines)
10000 loops, best of 3: 119 µs per loop

In [40]: %timeit eafp(lines)
100000 loops, best of 3: 4.2 µs per loop
Matt Messersmith
źródło
-4

Zasadniczo obsługa wyjątków powinna być bardziej odpowiednia dla języków OOP.

Drugi punkt to wydajność, ponieważ nie musisz wykonywać eachLine.finddla każdej linii.

Elalfer
źródło
7
-1: Wydajność jest wyjątkowo słabym powodem stosowania reguł ogólnych.
mattnz
3
Nie, wyjątki są całkowicie niezwiązane z OOP.
Pubby
-6

Myślę, że programowanie defensywne szkodzi wydajności. Powinieneś także wychwytywać tylko wyjątki, które zamierzasz obsłużyć, pozwól środowisku wykonawczemu zająć się wyjątkiem, którego nie wiesz, jak sobie poradzić.

Manoj
źródło
7
Jeszcze anotehr -1 za obawy o wydajność nad czytelnością, konserwowalność bla bla bla. Wydajność nie jest powodem.
mattnz
Czy mogę wiedzieć, dlaczego biegasz w okolicy, dystrybuując -1 bez wyjaśnienia? Programowanie defensywne oznacza więcej linii kodu, co oznacza gorszą wydajność. Czy ktoś zechce to wyjaśnić przed zestrzeleniem wyniku?
Manoj
3
@Manoj: O ile nie dokonałeś pomiaru za pomocą profilera i nie znalazłeś bloku kodu, który jest niedopuszczalnie wolny, kod zapewniający czytelność i łatwość konserwacji znacznie przed wydajnością.
Daenyth,
To, co powiedział @Manoj z dodatkiem, że mniej kodu oznacza ogólnie mniej pracy przy debugowaniu i konserwacji. Czas działania dewelopera na mniej niż ten doskonały kod jest niezwykle wysoki. Zakładam (podobnie jak ja), że nie piszesz idealnego kodu, wybacz mi, jeśli się mylę.
mattnz
2
Dzięki za link - Interesujące przeczytanie, że muszę się z tym zgodzić, do rzeczy ... Pracuję nad systemami krytycznymi dla życia, tak jak ja. System wydrukował ślad stosu, więc wiemy dokładnie, dlaczego 300 osób zmarło niepotrzebnie. .... ”tak naprawdę nie pójdzie zbyt dobrze na stanowisku świadka. Przypuszczam, że jest to jedna z tych rzeczy, w których każda sytuacja ma inną odpowiednią reakcję.
mattnz