Czy w poleceniach ' except` należy zawsze podawać typ wyjątku?

Podczas używania PyCharm IDE użycie except: bez typu wyjątku powoduje przypomnienie z IDE, że ta klauzula wyjątku to Too broad.

Czy powinienem ignorować tę radę? A może Pythonic zawsze określa typ wyjątku?
Author: dreftymac, 2013-02-10

7 answers

Prawie zawsze lepiej jest określić jawny typ wyjątku. Jeśli użyjesz nagiej klauzuli except:, możesz wyłapać wyjątki inne niż te, których spodziewasz się złapać - może to ukryć błędy lub utrudnić debugowanie programów, gdy nie robią tego, czego oczekujesz.

Na przykład, jeśli wstawiasz wiersz do bazy danych, możesz chcieć złapać wyjątek, który wskazuje, że wiersz już istnieje, więc możesz wykonać aktualizację.

try:
    insert(connection, data)
except:
    update(connection, data)

Jeśli podasz bare except:, można również złapać błąd gniazda wskazujący, że serwer bazy danych upadł. Najlepiej jest łapać tylko wyjątki, z którymi wiesz, jak sobie radzić - często lepiej jest, aby program zawiódł w punkcie wyjątku, niż kontynuować, ale zachowywać się w dziwny nieoczekiwany sposób.

Jeden przypadek, w którym możesz chcieć użyć gołego except: jest na najwyższym poziomie programu, który musisz zawsze uruchomić, jak serwer sieciowy. Ale wtedy musisz być bardzo ostrożny, aby zapisać wyjątki, inaczej nie da się ustalić, co jest nie tak. Zasadniczo w programie powinno być najwyżej jedno miejsce, które to robi.

Następstwem tego wszystkiego jest to, że Twój kod nigdy nie powinien działać raise Exception('some message'), ponieważ zmusza kod klienta do użycia except: (lub except Exception:, co jest prawie jako złe). Powinieneś zdefiniować wyjątek specyficzny dla problemu, który chcesz sygnalizować(być może dziedziczenie z jakiejś wbudowanej podklasy WYJĄTKÓW, takiej jak ValueError lub TypeError). Lub należy podnieść konkretne wbudowany wyjątek. Dzięki temu użytkownicy Twojego kodu mogą być ostrożni w wyłapywaniu tylko tych wyjątków, z którymi chcą się uporać.

 55
Author: babbageclunk,
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-04-16 12:19:28

Nie powinieneś ignorować porad tłumacza.

From the PEP-8 Style Guide for Python:

Gdy wyłapujesz wyjątki, wymień konkretne wyjątki, gdy możliwe zamiast używania nagiej klauzuli except:.

Na przykład:

 try:
     import platform_specific_module 
 except ImportError:
     platform_specific_module = None 

Naga klauzula except: łapie wyjątki SystemExit i KeyboardInterrupt, co utrudnia przerywa program za pomocą Control-C i może zamaskować inne problemy. Jeśli chcesz wyłapać wszystkie wyjątki sygnalizujące błędy programu, użyj Exception Exception: (bare Exception jest równoznaczne z Exception BaseException:).

Dobrą zasadą jest ograniczenie stosowania nagich klauzul "except" do dwóch przypadki:

Jeśli obsługa wyjątków będzie drukować lub logować traceback; przynajmniej użytkownik będzie świadomy, że wystąpił błąd. Jeśli kod musi wykonać jakąś pracę porządkową, ale wtedy pozwala na wyjątek propagować w górę z podbijam. spróbuj...wreszcie może być lepszym sposobem na zajmij się tą sprawą.

 25
Author: asheeshr,
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
2013-02-10 14:35:16

Not specfic to Python this.

Cały punkt wyjątków polega na tym, aby poradzić sobie z problemem jak najbliżej miejsca, w którym został spowodowany.

Więc zachowaj kod, który w wyjątkowych okolicznościach może wywołać problem i rozdzielczość "obok" siebie.

Rzecz w tym, że nie możesz znać wszystkich wyjątków, które mogłyby zostać rzucone przez kawałek kodu. Wszystko, co możesz wiedzieć, to to, że jeśli jest to powiedzmy, że plik nie znalazł wyjątku, możesz go uwięzić i monitować użytkownika aby uzyskać taki, który wykonuje lub anuluje funkcję.

Jeśli umieścisz try catch Okrągły, to bez względu na to, jaki problem nie było w rutynowych plików (tylko do odczytu, uprawnienia, UAC, naprawdę nie pdf, itp), każdy z nich wpadnie do pliku nie znaleziono catch, a użytkownik krzyczy "ale to jest tam, ten kod jest gówno"

Teraz jest kilka sytuacji, w których można złapać wszystko, ale należy je wybrać świadomie.

Są łapaniem, cofaniem niektórych lokalnych akcji (takich jak tworzenie lub blokowanie zasobu (otwarcie pliku na dysku, aby zapisać na przykład), a następnie rzucanie wyjątku ponownie, aby zająć się na wyższym poziomie)

Druga ty to nie obchodzi cię, Dlaczego poszło źle. Na przykład drukowanie. Możesz mieć cały haczyk, że, aby powiedzieć, że jest jakiś problem z drukarką, Rozwiąż to i nie zabijaj aplikacji z tego powodu. Na podobnej zasadzie, gdyby twój kod wykonał serię oddzielnych zadań używając jakiegoś harmonogramu, to chcę, żeby cała rzecz zginęła, bo jedno z zadań nie powiodło się.

Uwaga jeśli wykonasz powyższe, nie mogę polecić jakiegoś rodzaju rejestrowania WYJĄTKÓW, np. spróbuj catch log end, wystarczająco wysoko.

 6
Author: Tony Hopkinson,
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
2013-02-10 12:20:07

Możesz również złapać np. Control-C, więc nie rób tego, dopóki nie "rzucisz" go ponownie. Jednak w takim przypadku powinieneś raczej użyć "wreszcie".

 3
Author: Ulrich Eckhardt,
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
2013-02-10 11:45:07

Zawsze określaj typ wyjątku, jest wiele typów, których nie chcesz złapać, takich jak SyntaxError, KeyboardInterrupt, MemoryError itd.

 3
Author: Pavel Anossov,
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
2013-02-10 11:45:31

Oto miejsca, w których używam z wyjątkiem bez typu

  1. szybkie i brudne prototypowanie

To główne użycie w moim kodzie dla niezaznaczonych WYJĄTKÓW

  1. top level main () function, gdzie zapisuję każdy nieobciążony wyjątek

Zawsze dodaję to, aby kod produkcji nie rozlał stosów

  1. pomiędzy warstwami aplikacji

Mam na to dwa sposoby:

  • Pierwszy sposób: gdy warstwa wyższego poziomu wywołuje funkcję niższego poziomu, zawija wywołania w typowane wyjątki, aby obsłużyć" górne " wyjątki niższego poziomu. Ale dodaję ogólne polecenie except, aby wykryć nieobsługiwane wyjątki niższego poziomu w funkcjach niższego poziomu.

preferuję ten sposób, łatwiej jest mi wykryć, które wyjątki powinny zostać odpowiednio złapane:" widzę " problem lepiej, gdy wyjątek niższego poziomu jest rejestrowany przez wyższy poziom

  • drugi sposób, aby to zrobić: każdy najwyższy poziom funkcje warstw niższego poziomu mają swój kod zawinięty w ogólny wyjątek, aby wychwycić wszystkie nieobsługiwane wyjątki na danej warstwie.

niektórzy współpracownicy wolą ten sposób, ponieważ zachowuje wyjątki niższego poziomu w funkcjach niższego poziomu, gdzie "należą".

 1
Author: nipil,
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-03-12 08:43:34

Spróbuj tego:

try:
    #code
except ValueError:
    pass

Dostałem odpowiedź z tego linku, jeśli ktoś jeszcze natknie się na ten problem sprawdźcie to

 -4
Author: Mekanic,
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-06-26 23:53:43