Exception adalah error yang muncul saat program sedang jalan, dan try/except adalah cara menangkapnya supaya program gak berhenti. Bayangin kasir Warung Kopi Pak Darto yang membaca catatan pesanan. Kalau pelanggan menulis jumlahnya "dua", bukan "2", kasir yang kaku bengong lalu berhenti melayani. Kasir yang baik punya rencana cadangan: "coba baca angkanya; kalau gak bisa, minta ditulis ulang", lalu lanjut melayani pembeli berikutnya.
🧪 Tebakan cepat: blok
tryberisijumlah = int("3"). Di bawahnya adaexcept ValueError:yang mencetakbukan angka,else:yang mencetakjumlah: 3, danfinally:yang mencetakselesai. Berapa baris yang tercetak: satu, dua, atau tiga? Tebak dulu, jawabannya ada di bagian "Beberapa except, else, dan finally".
Membaca traceback
teks = "dua"
jumlah = int(teks)
print("Total:", 15000 * jumlah)
Traceback (most recent call last):
File "/home/darto/warung.py", line 2, in <module>
jumlah = int(teks)
ValueError: invalid literal for int() with base 10: 'dua'
- Baca dari bawah. Baris terakhir berisi jenis exception (
ValueError) dan pesannya:int()gak bisa mengubah'dua'jadi angka. - Di atasnya: nama file, nomor baris, dan baris kode yang gagal.
- Program berhenti di situ. Baris 3 gak pernah jalan.
- Jenis yang sering ketemu:
ValueError(nilainya salah,int("dua")),TypeError(tipenya salah,"Rp" + 15000atau10 / "abc"),ZeroDivisionError(dibagi nol),KeyError(key dictionary gak ada),IndexError(indeks list di luar batas),FileNotFoundError(file gak ada).
try dan except
teks = "dua"
try:
jumlah = int(teks)
print("Total:", 15000 * jumlah)
except ValueError:
print("Jumlah harus angka, bukan", teks)
print("Kasir lanjut melayani")
teks |
Yang terjadi | Output |
|---|---|---|
"3" |
blok try jalan sampai habis, except dilewati |
Total: 45000, lalu Kasir lanjut melayani |
"dua" |
int(teks) gagal, sisa blok try dilewati, except ValueError jalan |
Jumlah harus angka, bukan dua, lalu Kasir lanjut melayani |
try:berisi kode yang dicoba. Begitu satu baris di dalamnya melempar exception, sisa bloktrydilewati.except ValueError:menangkap exception jenis itu saja, lalu menjalankan bloknya. Program gak berhenti, jadi baris terakhir tetap jalan.except ValueError as e:menyimpan exception-nya die.print("Gagal:", e)mencetak pesannya:Gagal: invalid literal for int() with base 10: 'dua'.- Tangkap jenis yang spesifik.
except Exception:atauexcept:saja menangkap semuanya, termasuk salah ketik di kodemu sendiri.
try juga bisa ada di dalam fungsi, dan blok except boleh return nilai pengganti:
def per_orang(total, orang):
try:
return total // orang
except ZeroDivisionError:
return "Jumlah orang gak boleh 0"
print(per_orang(45000, 3)) # 15000
print(per_orang(45000, 0)) # Jumlah orang gak boleh 0
Ingat dari pelajaran operator: / selalu menghasilkan float. 10 / 2 adalah 5.0, sedangkan 45000 // 3 adalah 15000.
Beberapa except, else, dan finally
Pelanggan mau bayar patungan: total 45.000 dibagi rata ke sejumlah orang, yang diketik kasir sebagai teks.
total = 45000
teks = "3"
try:
orang = int(teks)
per_orang = total // orang
except ValueError:
print("Jumlah orang harus angka, bukan", teks)
except ZeroDivisionError:
print("Jumlah orang gak boleh 0")
else:
print("Bayar per orang:", per_orang)
finally:
print("Kasir siap lagi")
teks |
Yang terjadi | Output |
|---|---|---|
"3" |
try berhasil, jadi else jalan |
Bayar per orang: 15000, Kasir siap lagi |
"dua" |
int gagal: ValueError |
Jumlah orang harus angka, bukan dua, Kasir siap lagi |
"0" |
45000 // 0 gagal: ZeroDivisionError |
Jumlah orang gak boleh 0, Kasir siap lagi |
- Python mencocokkan
exceptdari atas ke bawah. Yang pertama cocok yang jalan, sisanya dilewati. else:jalan hanya kalautryselesai tanpa exception. Taruh di sana kode yang cuma boleh jalan kalau semuanya berhasil.finally:selalu jalan: saat berhasil, saat exception-nya tertangkap, bahkan saat gak tertangkap. Cocok untuk beres-beres, seperti menutup file atau melepas koneksi database.- Urutannya wajib
try,except,else,finally.elsetanpaexceptditolak:SyntaxError: expected 'except' or 'finally' block. - Di tebakan tadi,
int("3")berhasil, jadiexceptdilewati,elsemencetakjumlah: 3, danfinallymencetakselesai. Dua baris. Itu jawaban tebakannya.
Kalau except ZeroDivisionError dihapus dan teks berisi "0", finally tetap jalan duluan, baru setelah itu program berhenti:
Kasir siap lagi
Traceback (most recent call last):
File "/home/darto/warung.py", line 6, in <module>
per_orang = total // orang
~~~~~~^^~~~~~~
ZeroDivisionError: integer division or modulo by zero
raise dan exception buatan sendiri
class StokHabis(Exception):
pass
def ambil_roti(stok):
if stok == 0:
raise StokHabis("roti bakar habis")
return stok - 1
try:
ambil_roti(0)
except StokHabis as e:
print("Maaf,", e) # Maaf, roti bakar habis
raisemelempar exception dengan sengaja. Dengan jenis bawaan:raise ValueError("harga tidak boleh negatif"), seperti setter di pelajaran property.- Exception buatan sendiri adalah class turunan
Exception, pewarisan dari pelajaran inheritance.passsudah cukup sebagai isinya. - Nama yang jelas,
StokHabis, bisa ditangkap terpisah dari error lain. Tanpatry, baris terakhir traceback-nyaStokHabis: roti bakar habis.
⚠️ Jebakan yang sering ketemu
- Menangkap semuanya.
except Exception:ikut menelan salah ketik:orang = int(tkes)melemparNameError, tapi kasir mencetak "Jumlah orang harus angka" dan bug-nya tersembunyi. Tangkap jenis yang memang kamu tunggu. - Blok
trykepanjangan. Isitryhanya dengan baris yang bisa gagal. Sisanya taruh dielse, supaya exception dari baris lain gak ikut tertangkap diam-diam. - Menebak hasil
/.10 / 2adalah5.0, bukan5. Pembagian bulat pakai//. - Lupa bahwa
finallyselalu jalan. Jangan taruh kode yang cuma boleh jalan saat berhasil difinally. Tempatnya dielse.
TL;DR: Traceback dibaca dari bawah: jenis exception dan pesannya, lalu file dan barisnya. try: berisi kode yang dicoba, dan except JenisError: menangkap jenis itu supaya program lanjut; as e menyimpan pesannya. Beberapa except dicocokkan dari atas. else jalan hanya kalau try gak melempar exception, finally selalu jalan, dan urutannya try, except, else, finally: int("abc") dengan except ValueError dan finally mencetak pesan except-nya lalu pesan finally-nya. raise melempar exception sendiri, dan exception buatan sendiri adalah class turunan seperti class StokHabis(Exception). Tangkap jenis yang spesifik, bukan semua exception.