2.25. Menangani error

Sebagian besar masalah runtime di Python muncul sebagai exception -- cara bernama dan terstruktur untuk melaporkan bahwa sesuatu telah salah. ValueError, TypeError, KeyError, OSError, MemoryError semuanya adalah contoh; masing-masing adalah sebuah kelas, dan melempar satu akan menghentikan panggilan saat ini dan mencari handler dalam kode sekitarnya.

2.25.1. try / except

Bungkus blok kode dalam try untuk menangkap exception yang dilemparkannya:

try:
    n = int(input_text)
except ValueError:
    n = 0

Jika konversi int(...) gagal, kontrol melompat ke blok except alih-alih menyebarkan error lebih jauh. Jika input_text adalah string integer yang valid, blok except dilewati.

Satu try dapat memiliki beberapa blok except, masing-masing menangkap jenis error yang berbeda:

try:
    value = data[key]
except KeyError:
    value = None
except TypeError:
    value = -1

Python mencocokkan secara berurutan; yang pertama yang kelasnya cocok akan menangani masalah tersebut. Menangkap Exception (kelas dasar untuk hampir semua hal) menangani semua error; simpan itu untuk lapisan terluar program di mana alternatifnya adalah crash.

Peringatan

Bare except: (tanpa kelas setelah kata kunci) juga menangkap KeyboardInterrupt -- exception yang dikirimkan IDE ketika Anda menekan tombol stop untuk menginterupsi skrip yang berjalan. Loop yang dibungkus dalam bare except: pass akan menelan interupsi dan terus berjalan, tidak ada cara untuk menghentikan skrip kecuali dengan mematikan daya.

Sebaiknya gunakan except Exception: daripada bare except: ketika Anda benar-benar perlu menangkap secara luas. KeyboardInterrupt mewarisi dari BaseException, bukan Exception, sehingga except Exception: membiarkan tombol stop tetap berfungsi.

2.25.1.1. Memeriksa exception

Untuk membaca pesan yang dilampirkan pada exception, beri nama dengan as:

try:
    f = open("data.txt")
except OSError as e:
    print("could not open file:", e)

Variabel yang diikat oleh as hanya valid di dalam blok except.

2.25.2. else dan finally

Blok try memiliki dua tambahan opsional.

else hanya berjalan ketika try selesai tanpa melempar exception:

try:
    value = compute()
except ValueError:
    print("bad input")
else:
    print("got", value)

Menempatkan "apa yang harus dilakukan ketika berhasil" dalam else menjaga blok try tetap sempit -- hanya baris yang mungkin gagal yang masuk dalam try.

finally berjalan di akhir bagaimanapun -- baik try berhasil, melempar dan ditangani, atau melempar dan akan disebarkan:

try:
    do_work()
finally:
    cleanup()
Flow diagram showing the four possible paths through try / except / else / finally: success goes to else then finally; a caught exception goes to except then finally; an uncaught exception goes to finally then propagates.

finally selalu berjalan. else hanya berjalan pada jalur non-exception.

Untuk sebagian besar pola acquire/release, sebaiknya gunakan context manager daripada pasangan try / finally -- resource itu sendiri mengelola pembersihan sendiri.

2.25.3. Exception bawaan yang umum

Daftar singkat exception yang akan sering Anda temui:

  • ValueError -- tipe benar, nilai salah (bytes([300]) -- 300 memiliki tipe yang benar, tetapi berada di luar rentang byte yang valid yaitu 0..255).

  • TypeError -- tipe yang sama sekali salah (len(42)).

  • KeyError -- kunci yang hilang dalam dict.

  • IndexError -- indeks melewati akhir urutan.

  • AttributeError -- mengakses atribut yang tidak ada ("abc".foo).

  • OSError -- kegagalan filesystem atau I/O.

  • MemoryError -- kehabisan heap. Pada runtime dengan batasan memori, ini dapat terjadi selama operasi normal -- bukan hanya dalam kasus patologis.