Dlaczego "except: pass" jest złą praktyką programistyczną?

Często widzę komentarze do innych pytań dotyczących przepełnienia stosu, jak zniechęcać do używania except: pass. Dlaczego jest źle? Czasami po prostu nie obchodzi mnie, jakie są błędy i chcę po prostu kontynuować kod.

try:
    something
except:
    pass

Dlaczego używanie bloku except: pass jest złe? Co sprawia, że jest źle? Czy chodzi o to, że popełniłem błąd, czy o to, że popełniłem błąd?

Author: TylerH, 2014-02-04

15 answers

Jak się poprawnie domyśliłeś, są dwie strony: wyłapywanie dowolnego błędu poprzez podanie typu wyjątku po except i po prostu przekazywanie go bez podejmowania żadnych działań.

Moje wyjaśnienie jest "trochę" dłuższe-więc tl;dr to się psuje do tego:

  1. nie wyłapuj żadnego błędu . Zawsze określaj, z których WYJĄTKÓW jesteś gotowy do odzyskania i tylko je łap.
  2. staraj się unikać przechodzenia poza blokami. Chyba że wyraźnie pożądane, zwykle nie jest to dobry znak.

Ale przejdźmy do szczegółów:

Nie łap żadnego błędu

Używając bloku try, zazwyczaj robisz to, ponieważ wiesz, że istnieje szansa na wyrzucenie wyjątku. Jako takie, masz już przybliżone pojęcie Co może złamać i jaki wyjątek można wyrzucić. W takich przypadkach, można złapać wyjątek, ponieważ można pozytywnie odzyskać z niego. Oznacza to, że jesteś przygotowany na wyjątek i masz jakiś alternatywny plan, który zastosujesz w przypadku tego wyjątku.

Na przykład, gdy poprosisz użytkownika o wprowadzenie liczby, możesz przekonwertować dane wejściowe za pomocą int(), co może wywołać ValueError. Możesz łatwo to odzyskać, po prostu prosząc użytkownika, aby spróbował ponownie, więc złapanie ValueError i ponowne poproszenie użytkownika byłoby odpowiednim planem. Innym przykładem może być odczytanie konfiguracji z pliku, a ten plik nie istnieje. Ponieważ jest to plik konfiguracyjny, możesz mieć domyślną konfigurację jako zapasowy, więc plik nie jest dokładnie konieczny. Więc łapanie a FileNotFoundError i po prostu zastosowanie domyślnej konfiguracji byłoby dobrym planem tutaj. Teraz w obu tych przypadkach mamy bardzo konkretny wyjątek, którego oczekujemy i mamy równie konkretny plan, aby z niego wyjść. Jako takie, w każdym przypadku wyraźnie tylko except że pewne wyjątek.

Jednakże, jeśli mamy wyłapać Wszystko , to-oprócz tych wyjątków, z których jesteśmy gotowi się wyleczyć-istnieje również szansa, że otrzymamy wyjątki, których się nie spodziewaliśmy, i od których rzeczywiście nie możemy się wyleczyć; lub nie powinniśmy tego zrobić.

Weźmy przykład pliku konfiguracyjnego z góry. W przypadku braku pliku, po prostu zastosowaliśmy naszą domyślną konfigurację, a może postanowiliśmy w późniejszym czasie automatycznie zapisać konfigurację (tak następnym razem plik istnieje). Teraz wyobraź sobie, że dostajemy IsADirectoryError, lub PermissionError zamiast tego. W takich przypadkach prawdopodobnie nie chcemy kontynuować; nadal możemy zastosować naszą domyślną konfigurację, ale później nie będziemy mogli zapisać pliku. I jest prawdopodobne, że użytkownik chciał mieć również niestandardową konfigurację, więc używanie wartości domyślnych prawdopodobnie nie jest pożądane. Chcielibyśmy więc natychmiast poinformować o tym użytkownika i prawdopodobnie przerwać wykonywanie programu. Ale to nie jest coś, co my chcesz zrobić coś głęboko w małej części kodu; jest to coś ważnego na poziomie aplikacji, więc powinno być obsługiwane na górze-więc pozwól, aby wyjątek bańki w górę.

Inny prosty przykład jest również wspomniany w dokumencie idiomy Pythona 2. Tutaj w kodzie występuje prosta literówka, która powoduje jej złamanie. Ponieważ łapiemy każdy wyjątek, łapiemy również NameErrors i SyntaxErrors . Oba są błędami, które przytrafiają się nam wszystkim podczas programowanie; i oba są błędami, których absolutnie nie chcemy uwzględniać podczas wysyłania kodu. Ale ponieważ złapaliśmy je również, nie będziemy nawet wiedzieć, że wystąpiły tam i stracimy wszelką pomoc, aby poprawnie debugować.

Ale są też bardziej niebezpieczne wyjątki, na które raczej nie jesteśmy przygotowani. Na przykład SystemError jest zwykle czymś, co zdarza się rzadko i czego naprawdę nie możemy zaplanować; oznacza to, że dzieje się coś bardziej skomplikowanego, coś, co prawdopodobnie uniemożliwia nam kontynuowanie bieżącego zadania.

W każdym razie jest bardzo mało prawdopodobne, że jesteś przygotowany na wszystko w małej części kodu, więc tak naprawdę powinieneś łapać tylko te wyjątki, na które jesteś przygotowany. Niektórzy sugerują, aby przynajmniej złapać Exception ponieważ nie będzie zawierać rzeczy takich jak SystemExit i KeyboardInterrupt, które według projektu mają zakończyć Twoją aplikację, ale argumentowałbym, że jest to wciąż zbyt nieokreślone. Jest tylko jedno miejsce gdzie osobiście akceptuję przechwytywanie Exception lub po prostu dowolnego wyjątku , a to jest w pojedynczej globalnej obsłudze WYJĄTKÓW na poziomie aplikacji, która ma jeden cel, aby zarejestrować każdy wyjątek, na który nie byliśmy przygotowani. W ten sposób możemy zachować jak najwięcej informacji o nieoczekiwanych wyjątkach, które następnie możemy wykorzystać do rozszerzenia naszego kodu, aby obsłużyć je jawnie (jeśli możemy z nich odzyskać) lub-w przypadku błędu-do tworzenia przypadków testowych, aby upewnić się, że to się nie powtórzy. Ale oczywiście, że tylko działa, jeśli kiedykolwiek złapaliśmy tylko te wyjątki, których już się spodziewaliśmy, więc te, których się nie spodziewaliśmy, będą naturalnie bańki.

Staraj się unikać przechodzenia poza blokami

Kiedy wyraźnie wyłapujemy mały wybór konkretnych wyjątków, jest wiele sytuacji, w których będziemy w porządku, po prostu nic nie robiąc. W takich przypadkach samo posiadanie except SomeSpecificException: pass jest w porządku. Przez większość czasu jednak tak nie jest, ponieważ prawdopodobnie potrzebujemy kodu związanego z procesem odzyskiwania (jako wspomniane wyżej). Może to być na przykład coś, co powtarza akcję ponownie lub zamiast tego ustawia wartość domyślną.

Jeśli jednak tak nie jest, na przykład dlatego, że nasz kod jest już skonstruowany tak, aby powtarzał się, dopóki się nie powiedzie, to samo przejście jest wystarczająco dobre. Biorąc nasz przykład z góry, możemy poprosić Użytkownika o wprowadzenie numeru. Ponieważ wiemy, że użytkownicy lubią nie robić tego, o co ich prosimy, możemy po prostu umieścić go w pętli w pierwszej kolejności, więc może to wyglądać jak to:

def askForNumber ():
    while True:
        try:
            return int(input('Please enter a number: '))
        except ValueError:
            pass

Ponieważ staramy się, aż żaden wyjątek nie zostanie wyrzucony, nie musimy robić niczego specjalnego w bloku z wyjątkiem, więc jest to w porządku. Ale oczywiście, można argumentować, że przynajmniej chcemy pokazać użytkownikowi jakiś komunikat o błędzie, aby powiedzieć mu, dlaczego musi powtórzyć wejście.

W wielu innych przypadkach, samo przejście w except jest znakiem, że nie byliśmy przygotowani na wyjątek, który łapiemy. Chyba że te wyjątki są proste (jak ValueError lub TypeError), a powód, dla którego możemy przejść jest oczywisty, staraj się unikać tylko przechodzenia. Jeśli naprawdę nie ma nic do zrobienia (i jesteś tego absolutnie pewien), rozważ dodanie komentarza, dlaczego tak jest; w przeciwnym razie rozwiń blok z wyjątkiem, aby faktycznie zawierał kod odzyskiwania.

except: pass

Najgorsze jest połączenie obu. Oznacza to, że chętnie wyłapujemy każdy błąd, chociaż absolutnie nie jesteśmy na niego przygotowani i również nie robimy cokolwiek. Możesz przynajmniej zalogować błąd i prawdopodobnie ponownie go uruchomić, aby nadal zakończyć aplikację(jest mało prawdopodobne, że możesz kontynuować jak zwykle po błędzie MemoryError). Samo przejście nie tylko utrzyma aplikację nieco przy życiu( w zależności od tego, gdzie oczywiście złapiesz), ale także wyrzuci wszystkie informacje, uniemożliwiając odkrycie błędu-co jest szczególnie prawdziwe, jeśli nie jesteś tym, który go odkrywa.

Więc najważniejsze jest to: Wyłapuj tylko wyjątki, których naprawdę oczekujesz i jesteś gotowy do wyzdrowienia; wszystkie inne są prawdopodobnie albo błędami, które powinieneś naprawić, albo czymś, na co i tak nie jesteś przygotowany. Przekazywanie konkretnych wyjątków jest w porządku, jeśli naprawdę nie musisz coś z nimi robić. We wszystkich innych przypadkach jest to tylko oznaka domniemania i lenistwa. I zdecydowanie chcesz to naprawić.

 279
Author: poke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-28 20:24:09

Głównym problemem jest to, że ignoruje wszystkie i każdy błąd: Brak pamięci, procesor się pali, użytkownik chce się zatrzymać, program chce wyjść, Jabberwocky zabija użytkowników.

Tego już za wiele. W twojej głowie myślisz "chcę zignorować ten błąd sieciowy". Jeśli coś nieoczekiwanego pójdzie nie tak, wtedy twój kod po cichu kontynuuje i łamie się w zupełnie nieprzewidywalny sposób, którego nikt nie może debugować.

Dlatego powinieneś ograniczyć się do ignorowania tylko niektóre błędy i niech reszta minie.

 256
Author: Aaron Digulla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 19:36:29

Wykonanie twojego pseudo kodu dosłownie nie daje nawet żadnego błędu:

try:
    something
except:
    pass

Jakby to był idealnie poprawny fragment kodu, zamiast rzucać NameError. Mam nadzieję, że nie tego chcesz.

 70
Author: YS-L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 13:14:27

Dlaczego "except: pass" jest złą praktyką programistyczną?

Dlaczego jest źle?

try:
    something
except:
    pass

To łapie każdy możliwy wyjątek, w tym GeneratorExit, KeyboardInterrupt, i SystemExit - które są wyjątkami, których prawdopodobnie nie zamierzacie złapać. To to samo, co łapanie BaseException.

try:
    something
except BaseException:
    pass

Starsze wersje dokumentacji mówią :

Ponieważ każdy błąd w Pythonie powoduje wyjątek, użycie except: może spowodować wiele błędów programistycznych wygląda jak problemy z uruchomieniem, co utrudnia proces debugowania.

Hierarchia WYJĄTKÓW Pythona

Jeśli złapiesz klasę wyjątku rodzica, złapiesz również wszystkie ich klasy potomne. O wiele bardziej elegancko jest łapać tylko wyjątki, z którymi jesteś przygotowany.

Oto hierarchia WYJĄTKÓW Pythona 3 - czy naprawdę chcesz złapać ich wszystkich?:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
           +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

Nie rób tego

Jeśli używasz tej formy wyjątku obsługa:

try:
    something
except: # don't just do a bare except!
    pass

Wtedy nie będziesz mógł przerwać something bloku za pomocą Ctrl - C. Twój program przeoczy każdy możliwy wyjątek wewnątrz try bloku kodu.

Oto kolejny przykład, który będzie miał takie samo niepożądane zachowanie:

except BaseException as e: # don't do this either - same as bare!
    logging.info(e)

Zamiast tego spróbuj złapać tylko konkretny wyjątek, o którym wiesz, że szukasz. Na przykład, jeśli wiesz, że możesz uzyskać błąd wartości przy konwersji:

try:
    foo = operation_that_includes_int(foo)
except ValueError as e:
    if fatal_condition(): # You can raise the exception if it's bad,
        logging.info(e)   # but if it's fatal every time,
        raise             # you probably should just not catch it.
    else:                 # Only catch exceptions you are prepared to handle.
        foo = 0           # Here we simply assign foo to 0 and continue. 

Dalsze wyjaśnienie z innym przykład

Być może robisz to, ponieważ scrapujesz Sieć i dostajesz powiedzmy, UnicodeError, ale ponieważ użyłeś najszerszego wyłapywania WYJĄTKÓW, Twój kod, który może mieć inne podstawowe wady, będzie próbował uruchomić do końca, marnując przepustowość, czas przetwarzania, zużycie sprzętu, brak pamięci, zbieranie danych śmieci itp.

Jeśli inni ludzie proszą cię o dokończenie, aby mogli polegać na Twoim kodzie, rozumiem, że czujesz się zmuszony żeby się wszystkim zająć. Ale jeśli jesteś skłonny nie hałaśliwie jak rozwijać, będziesz miał możliwość skorygowania problemów, które mogą pojawiać się tylko sporadycznie, ale byłoby to długoterminowe kosztowne błędy.

Z bardziej precyzyjną obsługą błędów, kod może być bardziej wytrzymały.

 43
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-21 15:10:34
>>> import this
Zen Pythona, Tim Peters]} Piękne jest lepsze niż brzydkie.
Explicit jest lepszy niż implicit.
Proste jest lepsze niż złożone.
Kompleks jest lepszy niż skomplikowany.
Płaskie jest lepsze niż zagnieżdżone.
Sparse jest lepszy niż gęsty.
Liczy się czytelność.
Specjalne przypadki nie są wystarczająco specjalne, aby złamać zasady.
Chociaż praktyczność bije czystość.
błędy nigdy nie powinny mijać po cichu.
Chyba że wyraźnie wyciszony.
W obliczu dwuznaczności, Odrzuć pokusę zgadywania.
Powinien być jeden, a najlepiej tylko jeden, oczywisty sposób.
Chociaż ten sposób może nie być oczywisty na początku, chyba że jesteś Holendrem.
Teraz jest lepiej niż nigdy.
Chociaż nigdy nie jest często lepiej niż prawo teraz.
Jeśli implementacja jest trudna do wyjaśnienia, to zły pomysł.
Jeśli implementacja jest łatwa do wyjaśnienia, może to być dobry pomysł.
Przestrzenie nazw to świetny pomysł. zróbmy więcej takich!
Oto moja opinia. Kiedy znajdziesz błąd, powinieneś zrobić coś, aby go obsłużyć, np. napisać go w pliku logowania lub coś innego. Przynajmniej informuje Cię, że kiedyś wystąpił błąd.
 27
Author: Booster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 08:00:30

Powinieneś użyć co najmniej except Exception:, aby uniknąć wyłapywania WYJĄTKÓW systemowych, takich jak SystemExit lub KeyboardInterrupt. Oto link do dokumentów.

Ogólnie rzecz biorąc, powinieneś wyraźnie zdefiniować wyjątki, które chcesz złapać, aby uniknąć wyłapywania niechcianych WYJĄTKÓW. Powinieneś wiedzieć, jakie wyjątki ignorujesz .

 23
Author: Tupteq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 13:07:49

Po pierwsze, narusza dwie zasady Zen Pythona :

  • Explicit is better than implicit
  • błędy nigdy nie powinny mijać po cichu
To znaczy, że celowo popełniasz błąd w milczeniu. Co więcej, nie wiesz, który dokładnie wystąpił błąd, ponieważ except: pass wyłapie każdy wyjątek. Po drugie, jeśli spróbujemy oderwać się od Zen Pythona i mówić w kategoriach zdrowego rozsądku, powinieneś wiedz, że używanie except:pass pozostawia Ci brak wiedzy i kontroli w Twoim systemie. Zasadą jest, aby podnieść wyjątek, jeśli wystąpi błąd, i podjąć odpowiednie działania. Jeśli nie wiesz z góry, jakie działania powinny być, przynajmniej Zaloguj błąd gdzieś (i lepiej ponownie podnieś wyjątek):
try:
    something
except:
    logger.exception('Something happened')

Ale, zazwyczaj, Jeśli próbujesz złapać jakiś wyjątek, prawdopodobnie robisz coś złego!

 12
Author: Alexander Zhukov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-12 12:54:28

Konstrukcja except:pass zasadniczo ucisza wszelkie wyjątkowe warunki, które pojawiają się podczas uruchamiania kodu objętego blokiem try:.

Co sprawia, że ta zła praktyka jest to, że zwykle nie jest to, czego naprawdę chcesz. częściej pojawia się jakiś konkretny warunek, że chcesz uciszyć, a except:pass jest zbyt tępym narzędziem. Spowoduje to wykonanie zadania, ale maskuje również inne warunki błędów, których prawdopodobnie nie przewidziałeś, ale może bardzo dobrze chcesz poradzić sobie w inny sposób.

To, co sprawia, że jest to szczególnie ważne w Pythonie, to fakt, że przez idiomy tego języka, wyjątki niekoniecznie są błędami . Są one często używane w ten sposób, oczywiście, tak jak w większości języków. Ale Python w szczególności czasami używał ich do implementacji alternatywnej ścieżki wyjścia z niektórych zadań kodu, który nie jest tak naprawdę częścią normalnego działania, ale nadal jest znany z pojawiania się od czasu do czasu i może być nawet oczekiwany w większości sprawy. SystemExit został już wymieniony jako stary przykład, ale najczęstszym przykładem w dzisiejszych czasach może być StopIteration. Używanie WYJĄTKÓW w ten sposób wywołało wiele kontrowersji, zwłaszcza gdy Iteratory i generatory zostały po raz pierwszy wprowadzone do Pythona, ale ostatecznie pomysł zwyciężył.

 11
Author: The Spooniest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 15:10:33

Powód #1 został już podany-ukrywa błędy, których się nie spodziewałeś.

(#2) - to sprawia, że Twój kod jest trudny do odczytania i zrozumienia dla innych. Jeśli wyłapujesz FileNotFoundException podczas próby odczytania pliku, to dla innego programisty jest całkiem oczywiste, jaką funkcję powinien mieć blok 'catch'. Jeśli nie podasz wyjątku, potrzebujesz dodatkowego komentarza, aby wyjaśnić, co blok powinien zrobić.

(#3) - demonstruje leniwe programowanie. Jeśli używasz generycznego try/catch, oznacza to, że albo nie rozumiesz możliwych błędów w programie, albo nie wiesz, jakie wyjątki są możliwe w Pythonie. Wyłapanie określonego błędu pokazuje, że rozumiesz zarówno swój program, jak i zakres błędów, które rzuca Python. Jest to bardziej prawdopodobne, aby inni programiści i recenzenci kodu zaufali twojej pracy.

 11
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 02:25:47

Więc, jakie wyjście daje ten kod?

fruits = [ 'apple', 'pear', 'carrot', 'banana' ]

found = False
try:
     for i in range(len(fruit)):
         if fruits[i] == 'apple':
             found = true
except:
     pass

if found:
    print "Found an apple"
else:
    print "No apples in list"

Teraz wyobraź sobie try-except block to setki linii wywołań do złożonej hierarchii obiektów, a sam jest wywoływany w środku dużego drzewa wywołań programu. Kiedy program się nie uda, od czego zacząć szukać?

 11
Author: Ian Harvey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-06 10:27:25

Ogólnie można sklasyfikować każdy błąd/wyjątek w jednej z trzech kategorii :

  • Fatal: nie twoja wina, nie możesz im zapobiec, nie możesz od nich wyzdrowieć. Z pewnością nie powinieneś ich ignorować i kontynuować, i pozostawić swój program w nieznanym stanie. Po prostu pozwól, aby błąd zakończył Twój program, nic nie możesz zrobić.

  • Boneheaded: twoja własna wina, najprawdopodobniej z powodu niedopatrzenia, błędu lub błędu programistycznego. Ty powinien naprawić błąd. Ponownie, z pewnością nie należy ignorować i kontynuować.

  • Exogenne: można się spodziewać tych błędów w wyjątkowych sytuacjach, takich jak file not found lub connection finished. Powinieneś wyraźnie obsłużyć te błędy i tylko te.

We wszystkich przypadkach except: pass pozostawi Twój program tylko w nieznanym stanie, gdzie może spowodować więcej szkód.

 10
Author: Daniel Pelsmaeker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 17:01:27

Mówiąc najprościej, jeśli zostanie wyrzucony wyjątek lub błąd, coś jest nie tak. Może nie jest to coś bardzo złego, ale tworzenie, rzucanie i wyłapywanie błędów i wyjątków tylko ze względu na używanie poleceń goto nie jest dobrym pomysłem i rzadko się to robi. W 99% przypadków gdzieś był problem.

Problemy muszą być rozwiązane. Tak jak to jest w życiu, w programowaniu, jeśli po prostu zostawisz problemy w spokoju i starasz się je ignorować, nie znikną same. razy; zamiast tego stają się większe i mnożą. Aby zapobiec problem rośnie na Ciebie i uderzając ponownie dalej w dół drogi, albo 1) wyeliminować go i posprzątać bałagan potem, lub 2) zawierać go i posprzątać bałagan później.

Samo ignorowanie wyjątków i błędów i pozostawienie ich w ten sposób jest dobrym sposobem na doświadczanie wycieków pamięci, doskonałych połączeń z bazą danych, niepotrzebnych blokad w uprawnieniach do plików itp.

W rzadkich przypadkach problem jest tak znikomy, trywialne i-pomijając potrzebę spróbowania...catch block - samodzielny , że naprawdę nie ma po prostu bałaganu do posprzątania. Są to jedyne okazje, w których ta najlepsza praktyka niekoniecznie ma zastosowanie. Z mojego doświadczenia wynika, że to ogólnie oznacza, że cokolwiek robi kod jest w zasadzie małostkowe i zapomniane, a coś w rodzaju ponownych prób lub specjalnych wiadomości nie jest warte ani złożoności, ani trzymania wątku.

W mojej firmie zasadą jest prawie zawsze rób coś w bloku haczyków, a jeśli nic nie robisz, zawsze musisz umieścić komentarz z bardzo dobrym powodem, dlaczego nie. Nigdy nie możesz przejść ani opuścić pustego bloku, gdy jest coś do zrobienia.

 5
Author: Panzercrisis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 23:30:34

Moim zdaniem błędy mają powód, by się wydawać, że mój dźwięk jest głupi, ale tak właśnie jest. Dobre programowanie rodzi błędy tylko wtedy, gdy trzeba je obsłużyć. Również, jak czytałem jakiś czas temu, "pass-Statement jest instrukcją, która pokazuje, że kod zostanie wstawiony później", więc jeśli chcesz mieć puste except-statement, nie krępuj się tego robić, ale dla dobrego programu brakuje części. bo nie radzisz sobie z rzeczami, które powinieneś mieć. Pojawiające się wyjątki dają szansę na poprawienie dane wejściowe lub zmienić strukturę danych tak, aby te wyjątki nie wystąpiły ponownie (ale w większości przypadków (Network-exceptions, General input-exceptions) wyjątki wskazują, że następne części programu nie będą działać dobrze. Na przykład wyjątek NetworkException może wskazywać na zerwane połączenie sieciowe, a program nie może wysyłać/odbierać danych w kolejnych krokach programu.

Ale użycie bloku pass tylko dla jednego bloku execuption-block jest poprawne, ponieważ nadal różnisz się między typami WYJĄTKÓW, więc jeśli umieścisz wszystkie bloki WYJĄTKÓW w jednym, nie jest pusta:

try:
    #code here
except Error1:
    #exception handle1

except Error2:
    #exception handle2
#and so on

Można przepisać w ten sposób:

try:
    #code here
except BaseException as e:
    if isinstance(e, Error1):
        #exception handle1

    elif isinstance(e, Error2):
        #exception handle2

    ...

    else:
        raise

Więc nawet wiele bloków except z poleceniami pass może spowodować powstanie kodu, którego struktura obsługuje specjalne typy WYJĄTKÓW.

 5
Author: Sirac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 00:02:46

Wszystkie komentarze poruszone do tej pory są ważne. W miarę możliwości musisz określić, jaki wyjątek chcesz zignorować. Tam, gdzie to możliwe, musisz przeanalizować, co spowodowało wyjątek i ignorować tylko to, co miałeś zignorować, a nie resztę. Jeśli wyjątek powoduje, że aplikacja "Crash spektakularnie", to niech tak będzie, ponieważ o wiele ważniejsze jest, aby wiedzieć, że nieoczekiwane stało się, kiedy to się stało, niż ukrywanie, że problem kiedykolwiek wystąpił.

Z tym wszystkim, co powiedziane, nie bierz żadnych praktyka programowania jako podstawa. To głupie. Zawsze jest czas i miejsce, aby wykonać blok ignore-all-exceptions.

Innym przykładem idiotycznego paramount jest użycie operatora goto. Kiedy byłem w szkole, nasz profesor nauczył nas operatora goto tylko wspomnieć, że nigdy go nie używasz. Nie wierz ludziom, którzy mówią ci, że xyz nigdy nie powinien być używany i nie może być scenariusza, kiedy jest przydatny. Zawsze jest.

 4
Author: galets,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 20:52:01

Obsługa błędów jest bardzo ważna w programowaniu. Musisz pokazać użytkownikowi, co poszło nie tak. W bardzo niewielu przypadkach można zignorować błędy. Jest to bardzo zła praktyka programowania.

 2
Author: fastcodejava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-08 00:47:27