Przechwytuj wyjątki za pomocą funkcji Try z wyjątkiem w Pythonie

Programy w języku Python kończą się niepowodzeniem w czasie wykonywania, gdy operacje takie jak dostęp do pliku, analizowanie danych wejściowych lub wywołania sieciowe powodują wyjątki. Obchodzenie się z nimitry/exceptzapewnia responsywność aplikacji, zachowuje użyteczny kontekst i gwarantuje uporządkowanie.

Zanim zaczniesz — podstawowe zasady

  • Przechwytuj najbardziej specyficzne typy wyjątków, jakich oczekujesz (na przykładValueError,FileNotFoundError), a nie ogólne pojęcie.
  • Używaćelsena ścieżkę sukcesu ifinallydla kodu, który musi działać bez względu na wszystko.
  • Preferuj menedżerów kontekstu (with) dla plików i innych zasobów, aby uprościć czyszczenie.
  • Pozwól, aby nieoczekiwane błędy się rozprzestrzeniały; zaloguj je i podbij ponownie, zamiast po cichu je połykać.
  • Rezerwowe programy obsługi catch-all (except ExceptionLubexcept BaseException) dla granic najwyższego poziomu, gdzie możesz szybko ponieść porażkę lub jasno zgłosić porażkę.

Krok 1:Zidentyfikuj jedną ryzykowną operację, którą należy chronić.

raw = input("Select a fruit number (0-2): ")

Krok 2:Zakończ operacjętry/excepti obsługiwać jawne typy wyjątków.

try:
    selection = ["apple", "pear", "banana"][int(raw)]
    print("You chose:", selection)
except ValueError:
    print("Not a number.")
except IndexError:
    print("Choice out of range.")

Krok 3:Grupuj powiązane wyjątki, gdy odzyskiwanie jest identyczne.

try:
    selection = ["apple", "pear", "banana"][int(raw)]
except (ValueError, IndexError) as e:
    print("Invalid selection:", type(e).__name__)

Typowe szczególne wyjątki obejmująOSErrorrodzina (pliki),ValueErrorITypeError(dane),ZeroDivisionError(matematyka) iKeyError/IndexError(zbiory).

Metoda 2 — Użyj else i last, aby oddzielić sukces od czyszczenia

Krok 1:Dodaćelsedla kodu, który powinien działać tylko wtedy, gdy nic nie zawiedzie.

try:
    f = open("config.json", "r", encoding="utf-8")
except FileNotFoundError:
    print("No config file found.")
else:
    data = f.read()
    print("Loaded", len(data), "bytes.")
    f.close()

Krok 2:Dodaćfinallydo czyszczenia, które musi nastąpić niezależnie od tego, czy próba się powiodła, czy nie.

f = None
try:
    f = open("config.json", "r", encoding="utf-8")
    data = f.read()
except OSError as err:
    print("OS error:", err)
finally:
    if f:
        f.close()

Metoda 3 — Strzeż swojego punktu wejścia, aby szybko zakończyć się niepowodzeniem i zalogować się

Krok 1:Przenieś swój przepływ pracy domain()funkcjonować.

def main():
    # core workflow
    # ...
    return 0

Krok 2:Zakończ połączenie na najwyższym poziomietry/exceptaby zarejestrować nieoczekiwane błędy i zatrzymać program.

POWIĄZANY:Jak utworzyć venv w Pythonie

import logging, sys

logging.basicConfig(level=logging.INFO)

if __name__ == "__main__":
    try:
        code = main()
    except Exception:
        logging.exception("Unhandled error")
        sys.exit(1)
    sys.exit(code)

Krok 3:Zwraca niezerowy kod zakończenia w przypadku niepowodzenia sygnalizowania narzędziom automatyzacji, że przebieg nie powiódł się.

# in main(), return 1 or raise an exception when a critical step fails

Metoda 4 — Zarządzaj zasobami za pomocąwith(w końcu preferowane zamiast ręcznego)

Krok 1:Zastąp ręczne otwieranie/zamykanie menedżerem kontekstu, aby wymusić terminowe wydanie.

from pathlib import Path

try:
    with Path("data.txt").open("r", encoding="utf-8") as f:
        print(f.readline().strip())
except FileNotFoundError:
    print("Create data.txt first.")

Krok 2:Trzymaj tylko ryzykowne operacje w chronionym bloku, aby uniknąć przechwytywania niepowiązanych błędów.

try:
    with open("image.png", "rb") as fh:
        blob = fh.read()
except OSError as e:
    print("File access failed:", e)
# decode/process blob in a separate block

Metoda 5 — Podnoszenie, ponowne podnoszenie i łączenie wyjątków w celu wyczyszczenia ścieżek błędów

Krok 1:Zgłoś konkretny wyjątek, gdy warunek wstępny nie powiedzie się.

def parse_age(s: str) -> int:
    if not s.isdigit():
        raise ValueError("age must contain only digits")
    age = int(s)
    if age < 0:
        raise ValueError("age cannot be negative")
    return age

Krok 2:Zgłaszaj ponownie nieoczekiwane błędy po zalogowaniu, aby osoby dzwoniące również mogły je obsłużyć.

import logging

try:
    do_risky_thing()
except OSError as err:
    logging.error("OS error: %s", err)
    raise

Krok 3:Wyjątki łańcuchowe zraise ... from eaby zachować pierwotną przyczynę podczas dodawania kontekstu.

from pathlib import Path
import json

def load_json(path: str):
    try:
        text = Path(path).read_text(encoding="utf-8")
    except OSError as e:
        raise RuntimeError(f"Failed to read {path}") from e
    return json.loads(text)

Metoda 6 — Obsługa typu „catch-all” na granicach (stosuj oszczędnie)

Krok 1:Używaćexcept Exception as eaby przechwycić wszelkie błędy inne niż wychodzące z systemu, zapisać szczegóły i zdecydować, czy zatrzymać, czy ponowić próbę.

import traceback

try:
    risky()
except Exception as e:
    print(f"Unexpected {type(e).__name__}: {e}")
    traceback.print_exc()  # full stack trace
    # decide: raise, return error, or abort

Krok 2:Tylko złapBaseExceptionjeśli celowo przechwyciszKeyboardInterruptLubSystemExit, a następnie natychmiast ponownie podbij.

try:
    service_loop()
except BaseException as e:
    print(f"Caught {type(e).__name__}; shutting down cleanly.")
    raise  # never swallow interrupts or SystemExit

Metoda 7 — Obsługuj wiele błędów za pomocą grupy wyjątków i wyjątku* (Python 3.11+)

Krok 1:PodnieśExceptionGrouppodczas agregowania błędów z pracy równoległej lub wsadowej.

def run_tests(tests):
    errors = []
    for t in tests:
        try:
            t.run()
        except Exception as e:
            e.add_note(f"Test {t.name} failed")
            errors.append(e)
    if errors:
        raise ExceptionGroup("Batch failures", errors)

Krok 2:Używaćexcept*do obsługi tylko pasujących typów wyjątków w grupie.

try:
    run_tests(tests)
except* (ValueError, TypeError):
    print("Some data errors occurred.")
except* OSError:
    print("Some OS errors occurred.")

Szybkie wzorce rozwiązywania problemów

  • Analiza danych wejściowych: zawińint()Lubfloat()zexcept ValueErrori ponownie poproś użytkownika.
  • Plik we/wy: catchFileNotFoundError,PermissionErrorlub ogólnyOSErrori przejdź na ścieżkę zastępczą.
  • Wywołania sieciowe/API: przechwytuj przekroczenia limitu czasu/błędy połączenia specyficzne dla biblioteki i implementuj ograniczoną ponowną próbę z wycofywaniem.
  • Zawsze rejestruj typ i komunikat wyjątku; dla pełnych śladów użyjlogging.exception()Lubtraceback.print_exc().

Kilka skupionych wzorców, takich jak konkretneexceptklauzule,else/finally, a strażnicy najwyższego poziomu sprawią, że Twoje programy w języku Python będą bardziej odporne, bez ukrywania prawdziwych błędów.

Related Posts