Kursus Python / Menangani pengecualian dengan try, except, else, finally, dan raise

Penanganan pengecualian memisahkan kegagalan yang dapat dipulihkan dari kegagalan yang harus diteruskan kepada pemanggil. Batasi isi try pada operasi yang hendak dilindungi dan tangkap hanya kesalahan yang memang dapat ditangani agar cacat lain tidak tersembunyi.

Pahami jalur try, except, else, dan finally

Python menjalankan isi try terlebih dahulu. Jika muncul pengecualian yang cocok, eksekusi beralih ke except yang sesuai dan sisa isi try dilewati. Jika tidak ada penangan yang cocok pada lapisan itu, pengecualian diteruskan keluar, bukan diubah menjadi keberhasilan.

else dipakai untuk pekerjaan setelah blok try selesai tanpa pengecualian. Meletakkan pekerjaan itu di else menjaga agar kesalahan dari tahap lanjutan tidak ikut ditangkap oleh penangan operasi awal. finally dipakai untuk pembersihan ketika alur meninggalkan konstruksi tersebut, baik pada jalur normal maupun pengecualian.

Gunakan raise ketika program perlu menyatakan pelanggaran aturan. Masukan yang dapat diperbaiki pengguna berbeda dari kegagalan penyimpanan yang memerlukan tindakan pemanggil atau operator. Rujukan bentuk dan alurnya tersedia pada tutorial kesalahan dan pengecualian Python.

Jalankan nilai jumlah yang sah dan tidak sah

Simpan contoh lengkap sebagai exceptions_demo.py dengan encoding UTF-8 di folder latihan. Gunakan Python 3.12 atau lebih baru, lalu jalankan python exceptions_demo.py melalui lingkungan proyek. Contoh tidak membutuhkan berkas masukan atau paket tambahan.

def parse_amount(text):
    amount = int(text)
    if amount < 0:
        raise ValueError("amount must be nonnegative")
    return amount

for text in ["8000", "abc", "-1"]:
    try:
        amount = parse_amount(text)
    except ValueError as error:
        print("invalid:", text)
    else:
        print("accepted:", amount)
    finally:
        print("checked")

Keluaran yang diharapkan:

accepted: 8000
checked
invalid: abc
checked
invalid: -1
checked

String "8000" berhasil dikonversi dan memenuhi rentang, sehingga blok else mencetak accepted. String "abc" gagal di dalam int. String "-1" dapat dikonversi menjadi integer, tetapi ditolak oleh aturan jumlah nonnegatif yang dinyatakan melalui raise ValueError.

Kedua kegagalan ditangkap sebagai ValueError, tetapi penyebabnya berbeda. Program menampilkan label invalid yang sama lalu melanjutkan record berikutnya. Baris checked muncul setelah setiap percobaan karena diletakkan di finally. Baris itu berarti percobaan selesai ditangani pada alur ini, bukan berarti masukannya valid.

Variabel error berisi objek pengecualian dalam penangan. Untuk data latihan ini, Anda dapat mencetak str(error) sementara untuk membandingkan kesalahan konversi dengan pesan aturan nonnegatif. Jangan menganggap semua pesan internal layak ditampilkan untuk masukan nyata.

Tangani penyebab pada batas yang tepat

Contoh hanya mengantisipasi string jumlah yang salah format atau negatif. Jika salah satu unsur diganti dengan None, int(None) menghasilkan TypeError yang tidak ditangkap oleh penangan ValueError. finally tetap mencetak checked sebelum kegagalan diteruskan dan program berhenti. Menambah except Exception: pass hanya agar semua kasus tampak berhasil akan menyembunyikan kontrak input yang rusak.

Di dalam except, raise tanpa argumen meneruskan kembali pengecualian yang sedang ditangani. Sebaliknya, menangkap lalu return memberi nilai kepada pemanggil, sehingga alur pemanggil dapat melanjutkan sebagai hasil biasa. Tentukan apakah nilai pengganti memang pemulihan yang sah; jangan mengubah kegagalan tak dikenal menjadi nol atau list kosong tanpa kebijakan.

Jika lapisan aplikasi perlu mengubah jenis kesalahan sambil menjaga penyebab, bentuknya adalah raise RuntimeError("invalid source amount") from error. Hubungan penyebab membantu diagnosis tanpa memaksa pemanggil memahami seluruh rincian implementasi. Tetap pilih pesan yang tidak membocorkan data rahasia.

Untuk berkas, gunakan konteks with ketika sesuai agar penutupan dikelola secara terstruktur, seperti pada latihan berkas teks. Pembersihan manual pada finally harus memperhitungkan sumber daya yang belum berhasil dibuat. Kegagalan inisialisasi tidak boleh ditutupi oleh percobaan menutup variabel yang belum terikat.

Hindari return di dalam finally. Ia dapat mengganti nilai balik sebelumnya atau menekan pengecualian yang sedang diteruskan. Pembersihan yang tampaknya berhasil tidak boleh menjadikan kegagalan utama tidak terlihat. Selain itu, proses yang dihentikan paksa atau kegagalan sistem di luar alur Python biasa tidak memberi jaminan bahwa kode pembersihan sempat berjalan.

Uji keberhasilan, pemulihan, dan kegagalan yang diteruskan

  1. Ganti daftar input sementara menjadi ["0"]. Nol harus diterima dan diikuti checked.
  2. Ganti menjadi [""]. String kosong ditolak pada tahap konversi, lalu tetap diikuti checked.
  3. Pulihkan tiga masukan asli dan tampilkan pesan error sementara untuk membandingkan dua penyebab ValueError.
  4. Coba [None] sebagai percobaan terpisah untuk mengamati pengecualian yang tidak cocok. Hapus percobaan ini dan pulihkan program asli setelah memahami bahwa keluaran pembersihan bukan keluaran sukses.

Periksa urutan keluaran serta apakah proses berhenti atau melanjutkan. Pengujian yang hanya memeriksa satu nilai akhir dapat melewatkan record yang tidak diproses, pemulihan palsu, atau pembersihan yang menutupi penyebab.

Pesan pengecualian dan nilai masukan dapat memuat token, kata sandi, atau data pribadi. Berikan penjelasan yang membantu pengguna memperbaiki masukan, lalu simpan konteks diagnosis hanya sebanyak yang diperlukan dan di tempat yang sesuai. Mencatat kesalahan bukan alasan untuk menyalin seluruh data mentah.