Pernyataan try memungkinkan program menangkap kondisi gagal saat berjalan, alih-alih langsung berhenti dengan traceback. Objek yang mewakili kondisi gagal tersebut disebut exception. Mekanismenya disusun dalam empat blok yang saling melengkapi, yaitu try, except, else, dan finally. Topik ini membahas fungsi setiap blok beserta aturan urutannya, cara menangkap lebih dari satu jenis exception, dan kesalahan yang sering muncul ketika penangkapannya ditulis terlalu luas.
Struktur dasar try dan except#
Blok try berisi pernyataan yang berpotensi menimbulkan exception, sedangkan blok except berisi penanganan untuk jenis exception yang disebutkan setelah kata except. Apabila blok try selesai tanpa exception, blok except dilewati sepenuhnya. Apabila exception yang terjadi cocok dengan jenis yang ditangkap, eksekusi berpindah ke blok except, lalu program berlanjut ke pernyataan sesudah pernyataan try. Pola ini menjaga program tetap berjalan pada kondisi gagal yang dapat diantisipasi, misalnya masukan yang tidak sesuai format.
try:
angka = int("12a")
print("konversi berhasil:", angka)
except ValueError:
print("konversi gagal: teks bukan bilangan bulat")
print("program berlanjut")konversi gagal: teks bukan bilangan bulat
program berlanjutFungsi int() menimbulkan ValueError apabila teksnya bukan bilangan bulat. Karena exception itu ditangkap, program tidak mencetak traceback dan tidak berhenti, tetapi melanjutkan ke pernyataan terakhir. Sebaliknya, blok try yang berhasil, misalnya int("12"), menjalankan seluruh isinya dan melewati except tanpa jejak.
Kata kunci as mengikat objek exception ke sebuah nama, sehingga jenis dan pesannya dapat dibaca oleh program. Informasi itu berguna untuk log karena menyebut penyebab kegagalan secara lengkap.
try:
angka = int("x7")
except ValueError as e:
print(type(e).__name__, "-", e)ValueError - invalid literal for int() with base 10: 'x7'Pesan pada keluaran menyebut teks yang gagal dikonversi, sehingga penyebabnya jelas tanpa perlu membaca ulang kode. Pola ini dipakai pula pada contoh berikutnya agar setiap penanganan menyertakan informasi yang relevan. Objek exception juga membawa atribut dan metodenya sendiri, yang dibahas lebih lanjut pada topik hierarki exception.
Klausa else dan finally#
Urutan lengkapnya memiliki aturan eksekusi yang tegas. Blok else dijalankan hanya apabila blok try selesai tanpa exception, sehingga cocok untuk kode yang hanya sah setelah operasi utamanya berhasil. Blok finally dijalankan selalu, baik exception terjadi maupun tidak, dan tetap dijalankan pula ketika exception tidak tertangkap. Diagram berikut merangkum alurnya.
def baca_angka(teks):
try:
angka = int(teks)
except ValueError:
print("except: teks tidak dapat dikonversi")
return None
else:
print("else: konversi berhasil")
return angka
finally:
print("finally: selesai memproses", repr(teks))
print("hasil:", baca_angka("150"))
print("hasil:", baca_angka("1z5"))else: konversi berhasil
finally: selesai memproses '150'
hasil: 150
except: teks tidak dapat dikonversi
finally: selesai memproses '1z5'
hasil: NoneUntuk masukan 150, blok try berhasil sehingga else mencetak pesan keberhasilannya, sedangkan finally tetap tercetak sebelum fungsi mengembalikan nilainya. Untuk masukan 1z5, blok except yang bekerja dan finally tetap tercetak sesudahnya. Urutan cetakan menunjukkan bahwa finally selalu menjadi blok terakhir yang dijalankan sebelum fungsi benar-benar kembali.
Kekuatan finally paling terlihat ketika exception tidak tertangkap di dalam fungsinya.
def proses(angka):
try:
hasil = 10 / angka
print("hasil:", hasil)
finally:
print("finally: pembersihan tetap dijalankan")
return hasil
try:
proses(5)
proses(0)
except ZeroDivisionError as e:
print("ditangkap di luar:", type(e).__name__)hasil: 2.0
finally: pembersihan tetap dijalankan
finally: pembersihan tetap dijalankan
ditangkap di luar: ZeroDivisionErrorException ZeroDivisionError timbul di dalam pemanggilan proses(0), tetapi blok finally milik fungsi itu tetap mencetak pesannya sebelum exception mencapai except di pemanggil. Inilah alasan finally digunakan untuk pembersihan yang tidak boleh tertinggal dalam keadaan apa pun, misalnya menutup koneksi atau melepaskan kunci (lock).
Menangkap beberapa jenis exception#
Satu pernyataan try boleh memiliki lebih dari satu klausa except. Klausa-klausa diperiksa berurutan dari atas ke bawah, dan hanya yang pertama cocok yang dijalankan. Karena itu, jenis yang lebih spesifik ditulis lebih dahulu, sedangkan jenis yang lebih umum ditulis di akhir. Beberapa jenis yang penanganannya sama dapat digabung dalam satu klausa berbentuk tuple.
def bagi(a, b):
try:
hasil = a / b
except ZeroDivisionError:
print("except: pembagi tidak boleh nol")
return None
except TypeError:
print("except: tipe argumen tidak cocok")
return None
else:
print("else: hasil pembagian", hasil)
return hasil
bagi(10, 2)
bagi(10, 0)
bagi(10, "2")else: hasil pembagian 5.0
except: pembagi tidak boleh nol
except: tipe argumen tidak cocokPembagian 10 dengan 2 berjalan normal melalui else. Pembagian dengan 0 memicu ZeroDivisionError, sedangkan string “2” memicu TypeError karena operator / tidak menerima campuran angka dan string. Kedua kegagalan itu ditangani klausa yang berbeda, sehingga pesannya masing-masing spesifik.
for teks in ["12", None, "3x"]:
try:
angka = int(teks)
print("valid:", angka)
except (ValueError, TypeError) as e:
print("ditolak:", type(e).__name__)valid: 12
ditolak: TypeError
ditolak: ValueErrorBentuk tuple menangkap ValueError dan TypeError dengan penanganan yang sama, dan objek exceptionnya tetap dapat diikat dengan as. Sebaliknya, apabila jenis yang ditulis tidak mencakup exception yang terjadi, misalnya hanya TypeError padahal yang terjadi ValueError, exception itu tidak tertangkap dan program berhenti dengan traceback.
Kesalahan umum#
Kesalahan pertama adalah menulis except tanpa jenis, yang biasa disebut bare except. Bentuk ini menangkap hampir semua exception, termasuk SystemExit dan KeyboardInterrupt yang seharusnya dibiarkan menghentikan program.
try:
raise SystemExit("program ingin berhenti")
except:
print("tertangkap oleh except tanpa jenis")tertangkap oleh except tanpa jenisSystemExit biasanya muncul ketika fungsi sys.exit() dipanggil. Dengan except tanpa jenis, sinyal berhenti itu ikut tertangkap sehingga program tidak pernah selesai seperti seharusnya.
Kesalahan kedua adalah urutan klausa yang terbalik. Karena pemeriksaan berhenti pada klausa pertama yang cocok, except Exception yang ditulis di atas except ValueError akan menelan seluruh ValueError lebih dahulu, dan klausa yang spesifik tidak pernah tercapai. Aturannya sederhana, yaitu dari yang spesifik ke yang umum.
Kesalahan ketiga adalah letak klausa else. Klausa tersebut hanya sah ditulis sesudah seluruh except dan sebelum finally. Penulisan else sesudah finally ditolak interpreter dengan SyntaxError, dan else tanpa satu pun except juga tidak sah. Apabila yang dibutuhkan hanya jaminan pembersihan tanpa penanganan, pasangan try dan finally saja sudah cukup.
Ringkasan#
- Blok
trymemuat pernyataan berisiko, blokexceptmenangkap jenis yang disebutkan, dan kata kunciasmengikat objek exceptionnya. - Blok
elsedijalankan hanya apabilatryselesai tanpa exception, sedangkanfinallydijalankan selalu, termasuk ketika exception diteruskan ke pemanggil. - Klausa
exceptdiperiksa dari atas ke bawah dan hanya yang pertama cocok yang dijalankan, sehingga jenis yang spesifik ditulis lebih dahulu. excepttanpa jenis menangkap hampir semua exception, termasukSystemExitdanKeyboardInterrupt, sehingga jenisnya selalu disebutkan secara eksplisit.
Referensi#
- Errors and Exceptions — Python Software Foundation — Tutorial resmi tentang penanganan exception dengan try, except, else, dan finally.
- The try statement — Python Software Foundation — Referensi bahasa untuk semantik lengkap keempat blok pada pernyataan try.
- Built-in Exceptions — Python Software Foundation — Daftar kelas exception bawaan yang dapat ditangkap oleh except.