Tutorial Python untuk bukan pengatur cara/Menangani kecacatan

Daripada Wikibooks
Pergi ke pandu arah Pergi ke carian


...atau bagaimana harus menangani ralat[sunting]

Jadi, sekarang anda memiliki program yang sempurna, ia berjalan lancar melainkan satu perkara, ia runtuh apabila input tak sah dimasukkan pengguna. Jangan bimbang, kerana Python mempunyai sebuah struktur kawalan istimewa untuk anda. Ia digelar try dan ia cuba melakukan sesuatu. Ini satu contoh sebuah program yang bermasalah:

print "Taip Control C atau -1 untuk keluar"
nombor = 1
while nombor != -1:
    nombor = int(raw_input("Masukkan sebuah nombor: "))
    print "Anda memasukkan: ", nombor

Perhatikan apabila anda memasukkan @#& outputnya berupa ini:

Traceback (innermost last):
 File "try_less.py", line 4, in ?
    number = int(raw_input("Masukkan sebuah nombor: "))</source>

ValueError: invalid literal for int(): @#&

Seperti yang anda dapat lihat fungsi int() tidak berapa gemar dengan nombor @#& (dan memang sepatutnya demikian). Baris terakhir menunjukkan apa masalahnya; Python telah menemui ValueError (Ralat nilai). Bagaimana harus program kita menangani masalah ini? Apa yang harus kita buat ialah, pertamanya: letakkan kod yang menimbulkan ralat itu dalam blok try (cuba), dan keduanya: beritahu Python bagaimana kita mahu ralat ValueError dikendalikan.

Program berikut melakukan ini:

print "Taip Control C atau -1 untuk keluar"
nombor = 1
while nombor != -1:
    try:
        nombor = int(raw_input("Masukkan nombor: "))
        print "Anda telah memasukkan: ", nombor
    except ValueError:
        print "Itu bukan nombor."

Sekarang bila kita laksanakan program baru dan memberinya input seperti @#&, program itu akan memberitahu kita bahawa "Itu bukan nombor." dan meneruskan apabila yang dilakukannya sebelum itu.

Apabila program anda kerap mengalami ralat yang dapat anda perbetulkan, letakkan kod dalam blok try, dan letakkan cara untuk mengendalikan ralat itu dalam blok except (kecuali).

Berikut ini sebuah contoh Pengendalian Ralat yang lebih kompleks.

# Program by Mitchell Aikens 2012
# No copyright.
import math

def utama():
	berjaya = 0
	while (berjaya == 0):
		try:
			epak()
			berjaya = 1
		except ValueError:
			print "Ralat. Sila masukkan nilai integer."
			tahun = 0
		except NameError:
			print "Ralat. Sila masukkan nilai integer."
			tahun = 0
		except SyntaxError:
			print "Ralat. Sila masukkan nilai integer."
			tahun = 0
		finally:
			print "Program Selesai"

def epak():
    ## P: epak ialah cara menghitung umur Bulan
    ## pada satu Januari
    tahun = int(input("Ini tahun apa?\n"))
    C = tahun/100
    nilai_epak = (8 + (C/4) - C + ((8*C + 13)/25) + 11 * (tahun%19))%30
    print "Epak ialah: ", nilai_epak

utama()

Pengaturcaraan di atas menggunakan konsep-konsep daripada pelajaran dahulu dan juga pelajaran semasa.

Mari kita lihat bahgian-bahagian program di atas.

Selepas kita memberi definisi fungsi bernama "utama", kita memberitahu program bahawa kita mahu ia "mencuba" fungsi yang bernama "epak". Ia melakukannya "sementara" (while) ia tidak "berjaya". Pentafsir kemudian pergi ke baris tahun = int(input("Ini tahun apa?\n")). Pentafsir kemudiannya mengambil nilai yang dimasukkan pengguna dan menstor nilai tersebut dalam sebuah pemboleh ubah bernama "tahun".

Jika nilai yang dimasukkan bukan integer atau nombor apung (yang akan diubah menjadi interpreter oleh penaksir), sebuah pengecualian atau exception akan dizahirkan, dan pelaksanaan blok try berakhir, sejurus sebelum berjaya diumpukkan dengan nilai <Maricode>1.

Mari kita lihat beberapa pengecualian:

Program di atas tidak memiliki klausa except bagi setiap pengecualian yang mungkin timbul oleh sebab banyak penyebab pengecualian.

Jika nilai yang dimasukkan untuk "tahun" aksara abjad, sebuah pengecualian NameError akan ditimbulkan. Dalam program di atas, ini dilakukan oleh baris except NameError:, dan pentafsir akan melaksanakan kenyataan print di bawah except NameError:, kemudian ia menetapkan nilai "tahun" kepada 0 sebagai tindakan berjaga-jaga, lalu mengosongkannya daripada mengandungi nombor yang bukan angka. Pentafsir kemudiannya pulang kepada baris pertama gelung while, dan proses bermula sekali lagi.

Pengecualian lain yang mungkin kita milik akan menjalani proses yang sama dengan yang di atas. Jika sebuah pengecualian timbul, dan terdapat pula klausa "except" dalam program kita, pentafsir akan pergi ke kenyataan di bawah klausa yang berkaitan dan melaksanakan klausa-klausa tersebut.

Kenyataan finally kadang-kalanya digunakan bagi mengendali pengecualian. Lihatnya sebagai sebagai perkara istimewa. Kenyataan-kenyataan di bawah klausa finally akan terlaksana tidak kira sama ada kita menimbulkannya atau tidak. Kenyataan finally akan terlaksana selepas setiap klausa try atau except sebelumnya.

Di bawah ini ialah contoh lebih ringkas. Kita tidak berada dalam gelung dan klausa finally terlaksana tanpa mengambil kira kehadiran pengecualian.

#Program By Mitchell Aikens 2012
#Not copyright.

def main():
    try:
        nombor = int(input("Sila masukkan nombor:\n"))
        separuh = nombor/2
        print "Nilai separuh nombor yang anda masukkan ialah ",separuh
    except NameError:
        print "Ralat."
    except ValueError:
        print "Ralat."
    except SyntaxError:
        print "Ralat."
    finally:
        print "Saya melaksanakan klausa 'finally'."
        
main()

Jika kita masukkan nilai abjad bagi baris nombor = int(input("Sila masukkan nombor:\n")), outputnya kelihatan seperti berikut:

Sila masukkan nombor:
t
Error.
Saya melaksanakan klausa 'finally'.

Latihan[sunting]

Tingkat naik program nombor telefon (dalam bahagian IO Fail) supaya ia tidak nahas jika pengguna tidak memasukkan sebarang data di menu.