Tutorial ini menerangkan Pengendalian Pengecualian dalam Python menggunakan blok Try Except dengan bantuan contoh pengaturcaraan:
Dua jenis ralat boleh menyebabkan program Python berhenti secara tiba-tiba iaitu Sintaks Ralat dan Pengecualian . Dalam tutorial ini, kami akan membincangkan jenis ralat kedua (Pengecualian) di bawah beberapa topik penting.
Kami akan mendapat banyak manfaat daripada pengendalian pengecualian dalam aplikasi kami seperti:
- Membuat aplikasi yang mantap.
- Membuat kod yang bersih dan bebas ralat.
Python Try Except
Satu berita baik ialah Python mempunyai bilangan pengecualian terbina dalam yang baik untuk menangkap ralat dalam kod kami. Selain itu, ia memberi kami peluang untuk mencipta pengecualian tersuai apabila tiada pengecualian terbina dalam memenuhi keperluan kami.
Apakah Pengecualian
Jadi apakah pengecualian dalam Python? Secara ringkasnya, setiap kali jurubahasa Python cuba melaksanakan kod yang tidak sah, ia menimbulkan pengecualian, dan dalam kes di mana pengecualian sedemikian tidak dikendalikan, ia mengganggu aliran biasa arahan program dan mencetak jejak balik.
Mari kita buat kod yang tidak sah dan lihat cara penterjemah Python akan bertindak balas.
Buka shell Python dan jalankan kod berikut.
>>> 50/0
Ini adalah salah satu daripada kesilapan yang paling biasa dalam pengaturcaraan. Kod di atas cuba membahagikan nombor 50 dengan 0 (sifar). Pythonpembolehubah openFile sebelum ia ditetapkan.
Helah kecil di sini ialah menggunakan pengendali pengecualian di dalam blok akhir.
def readFile(file_path): try: openFile = open(file_path,'r') # Open a file as read-only print(openFile.readline()) # Read first line of file content except FileNotFoundError as ex: print(ex) finally: try: print("Cleaning...") openFile.close() except: # catches all exceptions pass # Ignore this error because we don't care. if __name__ == '__main__': filePath = './text.txt' readFile(filePath)
Jika blok percubaan kami menimbulkan FileNotFoundError, maka kami akan mempunyai output berikut
Raise Exception
Satu berita baik tentang pengecualian Python ialah kita boleh dengan sengaja membesarkan mereka. Pengecualian dinaikkan dengan penyataan raise .
Pernyataan raise mempunyai sintaks berikut:
raise [ExceptionName[(*args: Object)]]
Buka terminal dan naikkan sebarang objek pengecualian daripada Pengecualian terbina Python. Sebagai contoh, jika kami menaikkan ZeroDivisionError:
>>> raise ZeroDivisionError("Can't divide by zero")
Kami akan mendapat jejak balik:
Jadi, mengapakah penting untuk menimbulkan pengecualian?
- Apabila bekerja dengan pengecualian tersuai.
- Semasa pemeriksaan kewarasan.
Kelas Pengecualian Tersuai
Pengecualian tersuai ialah yang anda buat untuk mengendalikan ralat yang khusus untuk keperluan anda. Caranya ialah, kami mentakrifkan kelas yang terbit daripada objek Pengecualian , kemudian kami menggunakan pernyataan raise untuk menaikkan kelas pengecualian kami.
Andaikan kami ingin menyemak input pengguna dan pastikan nilai input tidak negatif (semakan kewarasan). Sudah tentu, kami boleh meningkatkan pengecualian Python ValueError tetapi kami ingin menyesuaikan ralat dengan memberikannya nama khusus dan penjelasan sendiri seperti InputIsNegativeError . Tetapi pengecualian ini bukan Python terbina dalamPengecualian.
Maka pertama, kami mencipta kelas asas kami yang akan terbit daripada Pengecualian.
class CustomError(Exception): "Base class exception for all exceptions of this module" pass
Kemudian kami mencipta kelas pengecualian kami yang akan mewarisi kelas asas dan akan mengendalikan ralat khusus kami.
class InputIsNegativeError(CustomError): """Raised when User enters a negative value""" pass
Mari kita uji ini
try: value = int(input()) if value 0: raise InputIsNegativeError # Raise exception if value is negative except InputIsNegativeError: # catch and handle exception print("Input value shouldn't be negative")
Permintaan kod di atas untuk input pengguna dan semak sama ada ia negatif. Jika benar, ia menimbulkan pengecualian tersuai kami InputIsNegativeError yang kemudiannya ditangkap dalam pernyataan pengecualian.
Di bawah ialah kod lengkap:
class CustomError(Exception): "Base class exception for all exceptions of this module" pass class InputIsNegativeError(CustomError): """Raised when User enters a negative value""" pass if __name__ == '__main__': try: value = int(input("Input a number: ")) if value 0: raise InputIsNegativeError # Raise exception if value is negative except InputIsNegativeError: # catch and handle exception print("Input value shouldn't be negative")
Jika nilai input ialah nombor negatif seperti -1, maka kita akan mempunyai output:
Semak dokumen Python untuk mendapatkan butiran lanjut tentang pengecualian tersuai Python.
Soalan Lazim
S #1) Bagaimanakah Python mengendalikan pengecualian?
Jawapan: Python mengendalikan pengecualian menggunakan pernyataan cuba-kecuali . Kod yang boleh menimbulkan pengecualian diletakkan dan dilaksanakan dalam blok cuba manakala blok kecuali memegang kod yang akan mengendalikan pengecualian jika ada yang timbul.
S #2) Apakah yang menimbulkan pengecualian dalam Python?
Jawapan: Setiap kali jurubahasa Python menemui kod yang tidak sah, ia menimbulkan pengecualian, iaitu cara Python sendiri untuk memberitahu kami bahawa sesuatu yang tidak dijangka berlaku. Kita juga boleh dengan sengaja menaikkan pengecualian menggunakan kenyataan raise .
S #3) Bagaimanakah Python mengendalikan berbilang pengecualian?
Jawapan: Python mengendalikan berbilang pengecualianmenggunakan sama ada satu kecuali blok atau berbilang kecuali blok.
Untuk satu blok, pengecualian diluluskan sebagai tuple: kecuali (Exception1, Exception2,..,ExceptionN) dan semakan Python untuk perlawanan dari kanan ke kiri. Dalam kes ini, tindakan yang sama diambil untuk setiap pengecualian.
Cara lain untuk menangkap semua pengecualian adalah dengan meninggalkan nama pengecualian selepas kata kunci kecuali.
except: # handle all exceptions here
Cara kedua ialah untuk menggunakan blok kecuali bagi setiap pengecualian:
except Exception1: # code to handle Exception1 goes here except Exception2: # code to handle Exception2 goes here except ExceptionN: # code to handle ExceptionN goes here
Dengan cara ini, anda boleh mengambil tindakan berasingan untuk setiap Pengecualian.
S #4) Mengapakah pengendalian Pengecualian penting dalam Python?
Jawapan: Faedah mengendalikan pengecualian dalam Python ialah kita boleh mencipta aplikasi yang mantap, bersih dan bebas ralat. Kami tidak mahu kod pengeluaran kami ranap kerana beberapa ralat, jadi kami mengendalikan ralat dan memastikan aplikasi kami berfungsi dan berjalan.
S #5) Bagaimanakah anda mengabaikan pengecualian dalam Python?
Jawapan: Untuk mengabaikan pengecualian dalam Python, gunakan kata kunci pass dalam blok kecuali. Katakan kita mahu mengabaikan pengecualian ValueError. Kami akan melakukannya dengan cara ini:
except ValueError: pass
Melainkan anda tahu perkara yang anda lakukan, adalah amalan buruk untuk mengabaikan pengecualian. Sekurang-kurangnya, maklumkan kepada pengguna tentang semua kemungkinan ralat.
Kesimpulan
Dalam tutorial ini, kami membincangkan: Pengecualian Python, Traceback; cara mengendalikan pengecualian dengan Cuba / Kecuali / Lain / Akhir sekali blok, cara Meningkatkan Pengecualian, dan akhirnya cara mencipta Pengecualian Tersuai kami sendiri.
Terima kasih kerana membaca!
jurubahasa melihat ini sebagai operasi yang tidak sah dan menimbulkan ZeroDivisionError, mengganggu program dan mencetak jejak balik.
Kita dapat melihat dengan jelas bahawa ZeroDivisionError ialah pengecualian yang dibangkitkan. Ia sememangnya cara Python sendiri untuk memberitahu kami bahawa tidak sesuai untuk membahagikan nombor dengan sifar. Walaupun dalam bahasa lain seperti JavaScript, ini bukan ralat; dan python melarang keras amalan ini.
Selain itu, adalah penting untuk mengetahui bahawa ini hanyalah objek pengecualian dan Python mempunyai banyak objek sedemikian terbina. Lihat dokumentasi rasmi Python ini untuk melihat semua Pengecualian Terbina Dalam Python.
Memahami Traceback
Sebelum kita mengendalikan pengecualian, saya fikir ia akan membantu untuk memahami apa sebenarnya yang akan berlaku jika pengecualian tidak dikendalikan dan cara Python melakukan yang terbaik untuk memberitahu kami tentang ralat kami.
Setiap kali Python menghadapi ralat, ia menimbulkan pengecualian. Jika pengecualian ini tidak dikendalikan, maka ia menghasilkan beberapa maklumat yang dipanggil Traceback. Jadi, apakah maklumat yang terkandung dalam surih balik ini?
Ia mengandungi:
- Mesej ralat yang memberitahu kami pengecualian yang dibangkitkan dan perkara yang berlaku sebelum pengecualian ini dinaikkan.
- Pelbagai nombor baris kod yang menyebabkan ralat ini. Ralat mungkin disebabkan oleh urutan panggilan fungsi yang dipanggil tindanan panggilan yang akan kita bincangkan kemudian di sini.
Walaupun ia adalahagak mengelirukan, kami berjanji bahawa contoh seterusnya akan membawa lebih banyak cahaya kepada pemahaman kami.
Imbas kembali surih yang telah dicetak daripada membahagikan 50 dengan 0 di atas, kita dapat melihat bahawa surih kembali mengandungi maklumat berikut:
- Fail “”: Ini memberitahu kami bahawa kod ini dijalankan daripada terminal konsol.
- baris 1: Ini memberitahu kami bahawa ralat berlaku dalam nombor baris ini.
- ZeroDivisionError: pembahagian dengan sifar: Ia memberitahu kita apa pengecualian yang dibangkitkan dan apa yang menyebabkannya.
Mari kita cuba contoh lain dan mungkin lihat bagaimana rupa timbunan panggilan . Buka editor, masukkan kod di bawah dan simpan sebagai tracebackExp .py
def stack1(numb): # 1 div = 0 # 2 stack2(numb, div) # 3 def stack2(numb, div): # 5 compute = numb/div # 6 print(compute) # 7 if __name__ == '__main__': # 9 numb = 5 # 10 stack1(numb) # 11
Buka terminal dalam direktori tempat fail ini ditemui dan dijalankan.
python tracebackExp.py
Anda akan melihat surih balik berikut:
Surih balik di atas mungkin kelihatan mengelirukan tetapi sebenarnya, tidak. Pythonistas menghasilkan cara terbaik untuk membaca jejak balik, iaitu dari bawah ke atas . Jadi, mari kita gunakan kebijaksanaan ini untuk mencuba dan memahami apa yang ditawarkan oleh jejak balik ini.
- Pada bahagian paling bawah, kita mendapat pengecualian yang dibangkitkan dan sebab ia dibangkitkan.
- Bergerak ke atas, kami mendapat nama fail tracebackExp .py tempat ralat ini berlaku, pengiraan yang menyebabkan ralat ini mengira = numb/div, timbunan fungsi2 dan baris nombor pautan 6 tempat pengiraan ini dilakukan .
- Bergerak ke atas, kami melihat bahawa stack2 kami berfungsitelah dipanggil dalam fungsi tindanan1 dalam baris nombor 3.
- Bergerak ke paling atas, kita melihat bahawa fungsi tindanan1 dipanggil dalam baris nombor 11. modul > memberitahu kami bahawa ia adalah fail yang sedang dilaksanakan.
Pengecualian Python Biasa
Pustaka Python mentakrifkan banyak sekali pengecualian terbina dalam. Anda boleh menyemak Dokumentasi Python atau memanggil fungsi local () terbina dalam seperti di bawah:
>>> dir(locals()['__builtins__'])
Kami tidak akan cuba menangani semua pengecualian ini, tetapi kami akan melihat beberapa pengecualian biasa yang mungkin anda akan temui.
#1) TypeError
Ia dibangkitkan apabila operasi atau fungsi digunakan pada objek daripada jenis yang tidak sesuai.
Contoh 1
Pertimbangkan atur cara di bawah. Ia mengambil dividen dan pembahagi, kemudian mengira dan mencetak hasil pembahagian dividen dengan pembahagi.
def compute_division(): dividend = int(input("Enter the dividend: ")) # cast string to int divisor = input("Enter the divisor: ") # no casting # Compute division result = dividend/divisor # print result print("The result of {}/{} is: {}".format(dividend, divisor, result)) if __name__ == '__main__': result = compute_division()
Kami meminta nilai dividen dan pembahagi daripada pengguna, tetapi kami terlupa untuk membuang rentetan pembahagi nilai menjadi integer. Jadi, kita berakhir dengan jenis dividen ialah integer( int ) dan jenis pembahagi ialah rentetan( str ). Kami kemudian mendapat TypeError kerana operator bahagian (/) tidak beroperasi pada rentetan.
Mungkin menarik minat anda untuk mengetahui bahawa tidak seperti Python, Javascript mempunyai Type Coercion yang pada asasnya menukar salah satu jenis operan kepada nilai yang setara dengan jenis operan yang lain apabila operan adalah daripadajenis yang berbeza.
#2) ValueError
Ini dibangkitkan apabila operasi atau fungsi menerima argumen yang mempunyai jenis yang betul tetapi nilai yang tidak sesuai.
Contoh 2
Pertimbangkan program kami dalam Contoh 1 di atas.
Jika pengguna memasukkan nilai alfanumerik untuk dividen seperti '3a', maka program kami akan meningkatkan pengecualian ValueError. Ini kerana, walaupun kaedah Python int() mengambil sebarang nombor atau rentetan dan mengembalikan objek integer, nilai rentetan tidak seharusnya mengandungi huruf atau sebarang nilai bukan angka.
#3) AttributeError
Pengecualian ini dibangkitkan semasa menetapkan atau merujuk atribut yang tidak wujud.
Contoh 3
Pertimbangkan program di bawah. Ia mengambil nombor dan mengira punca kuasa duanya menggunakan modul matematik Python
import math # import math library to gain access to its code def compute_square_root(number): # compute the square root using the math library result = math.sqr(number) return result if __name__ == '__main__': # get input to compute from user number = int(input("Compute Square root of: ")) # call function to compute square root
Apabila pengguna memasukkan nombor, program kami cuba menggunakan fungsi daripada modul matematik untuk mengira punca kuasa duanya tetapi hanya itu di sini, kami membuat kesilapan. Daripada sqrt, kami tersilap menaip sqr yang tidak wujud dalam modul matematik.
Jadi, kami cuba merujuk atribut sqr yang tidak wujud dan membawa kecuali AttributeError dibangkitkan. Kebanyakan kita sering melakukan kesilapan seperti ini. Jadi, anda tidak bersendirian.
Mengendalikan Pengecualian Dengan Try Except
Sebagai pengaturcara, satu perkara yang kebanyakan kita akan menghabiskan masa kita ialah menulis kod yang mantap iaituberdaya tahan. Kod yang tidak pecah kerana beberapa ralat. Dalam Python, kita boleh mencapai ini dengan melampirkan penyataan kita di dalam penyataan cuba – kecuali .
Pernyataan Python Try-Except
Pernyataan cuba-kecuali mempunyai struktur berikut:
try: #your code goes here except """Specify exception type(s) here""": #handle exception here
Mari sertakan kod dalam tracebackExp .py di dalam pernyataan cuba-kecuali.
def stack1(numb): # 1 div = 0 # 2 stack2(numb, div) # 3 def stack2(numb, div): # 5 try: # 6 compute = numb/div # 7 print(compute) # 8 except ZeroDivisionError as zde: # 9 print(zde) # 10 if __name__ == '__main__': # 12 numb = 5 # 13 stack1(numb) # 14 print("program continuous") # 15
Menjalankan kod ini akan menghasilkan output
Beginilah cara pernyataan cuba-kecuali berfungsi. Python melaksanakan kod dalam blok cuba baris 7-8 . Jika tiada kod tidak sah ditemui, maka kod dalam blok kecuali baris 10 dilangkau dan pelaksanaan diteruskan.
Tetapi, jika kod tidak sah ditemui, maka pelaksanaan serta-merta berhenti dalam cuba sekat dan semak sama ada pengecualian yang dibangkitkan sepadan dengan yang kami berikan dalam pernyataan kecuali baris 9 . Jika ia sepadan, maka blok kecuali dilaksanakan dan diteruskan. Jika tidak, maka program akan mengganggu.
Blok cuba biasanya mengandungi kod yang mungkin menimbulkan pengecualian manakala blok kecuali menangkap dan mengendalikan pengecualian.
Mengendalikan Berbilang Pengecualian Dengan Kecuali
Kami boleh mengendalikan berbilang pengecualian dengan sama ada satu "kecuali" atau berbilang "kecuali". Semuanya bergantung pada cara anda mahu mengendalikan setiap pengecualian.
#1) Mengendalikan Berbilang Pengecualian Dengan Satu Kecuali
try: #your code goes here except(Exception1[, Exception2[,...ExceptionN]]]): #handle exception here
Kaedah ini digunakan apabila kami mengesyaki bahawa kod kami mungkinmenimbulkan pengecualian yang berbeza dan kami mahu mengambil tindakan yang sama dalam setiap kes. Jadi, jika jurubahasa Python menemui padanan, maka kod yang ditulis dalam blok except akan dilaksanakan.
Mari kita pertimbangkan contoh kod Python di bawah
def get_fraction(value, idx): arr = [4,5,2,0] # a list of numbers idx_value = arr[idx] # if idx is > arr length, IndexError will be raised value/idx_value # if idx_value == 0, ZeroDivisionError will be raised if __name__ =='__main__': # set 'value' and 'idx' value = 54 idx = 3 # call function in a try-except statement. try: result = get_fraction(value, idx) print("Fraction is ", result) except (IndexError, ZeroDivisionError) as ex: print(ex)
Kami mempunyai dua kemungkinan pengecualian yang boleh dibangkitkan di sini, ZeroDivisionError dan IndexError . Jika mana-mana pengecualian ini dinaikkan, maka blok kecuali akan dilaksanakan.
Dalam kod di atas, idx=3, jadi idx_ nilai menjadi 0 dan nilai /idx_ value akan meningkatkan ZeroDivisionError
#2) Mengendalikan Berbilang Pengecualian Dengan Berbilang Pengecualian
try: #your code goes here except Exception1: #handle exception1 here except Exception2: #handle exception2 here except ExceptionN: #handle exceptionN here
Jika kita lebih suka mengendalikan setiap pengecualian secara berasingan, maka ini adalah cara anda boleh melakukannya.
Pertimbangkan contoh kod Python di bawah
def get_fraction(value, idx): arr = [4,5,2,0] # a list of numbers idx_value = arr[idx] # if idx is > arr length, IndexError will be raised value/idx_value # if idx_value == 0, ZeroDivisionError will be raised if __name__ =='__main__': # set 'value' and 'idx' value = 54 idx = 5 # call function in a try-excepts statement. try: result = get_fraction(value, idx) print("Fraction is ", result) except IndexError: print("idx of {} is out of range".format(idx)) except ZeroDivisionError: print("arr[{}] is 0. Hence, can't divide by zero".format(idx)) except Exception as ex: print(ex) print("Not sure what happened so not safe to continue, \ app will be interrupted") raise ex
Kami perhatikan di sini bahawa Pengecualian telah digunakan dalam pernyataan kecuali yang terakhir . Ini kerana objek pengecualian Pengecualian sepadan dengan sebarang pengecualian. Atas sebab ini, ia harus sentiasa terakhir, kerana Python akan berhenti menyemak pengendali pengecualian lain sebaik sahaja satu sepadan.
Dalam kod di atas, idx=5 , maka arr[idx ] akan menaikkan IndexError kerana idx lebih besar daripada panjang senarai arr
Selain itu, tidak pasti pengecualian yang dibangkitkan oleh permohonan anda tidak pernah selamat untuk meneruskan pelaksanaan. Itulah sebabnya kami mempunyai jenis Pengecualian untuk menangkap sebarang pengecualian yang tidak diramalkan. Kemudian, kami memaklumkan kepadapengguna dan mengganggu aplikasi dengan menaikkan pengecualian yang sama.
Cuba Pernyataan Lain
Ini ialah ciri pilihan pengendalian pengecualian dan membolehkan anda menambah kod yang anda mahu dijalankan apabila tiada ralat berlaku. Jika ralat berlaku, blok lain ini tidak akan dijalankan.
Pertimbangkan contoh kod Python di bawah, buka editor anda dan simpan kod sebagai elseTry.py
def fraction_of_one(divisor): value = 1/divisor # if divisor is zero, ZeroDivisionError will be raised return value if __name__ == '__main__': while True: try: # Get input from the user. # if input is not a valid argument for int(), ValueError will be raised divisor = int(input("Enter a divisor: ")) # call our function to compute the fraction value = fraction_of_one(divisor) except (ValueError, ZeroDivisionError): print("Input can't be zero and should be a valid literal for int(). Please, try again!") else: print("Value: ", value) break
Kami mendapat input daripada pengguna dan menggunakannya untuk membahagikan 1. Kami mempunyai dua kemungkinan pengecualian di sini, input pengguna tidak sah yang akan menyebabkan ValueError dan sifar(0) yang akan menyebabkan ZeroDivisionError . Pernyataan kecuali kami mengendalikan ralat ini.
Sekarang, kami mahu mencetak nilai nilai . Blok lain kami memastikan ia dicetak hanya jika blok percubaan kami dilaksanakan tanpa ralat. Ini penting kerana jika ralat berlaku dalam blok percubaan kami, nilai tidak akan ditentukan. Jadi, mengaksesnya akan menimbulkan satu lagi ralat.
Jalankan kod di atas dengan Python elseTry.py
Output di atas menunjukkan bahawa untuk input pertama, kami menaip 0 dan menekan ENTER. Memandangkan pembahagi kami menerima 0, 1/pembahagi menaikkan sifarDivisionError . Input kedua kami ialah k yang tidak sah untuk int (), oleh itu pengecualian ValueError dinaikkan.
Tetapi input terakhir kami ialah 9 yang sah dan sebagai Hasilnya, kami mendapat nilai " nilai " yang dicetak sebagai 0.1111111111111111
Cuba AkhirnyaPernyataan
Ini juga merupakan ciri pilihan pengendalian pengecualian dan akan sentiasa dijalankan tidak kira apa yang berlaku dalam pengendali pengecualian.
Iaitu:
- Sama ada pengecualian berlaku atau tidak
- Walaupun 'return' dipanggil dalam blok lain.
- Walaupun skrip dihentikan dalam blok lain
Jadi, jika kami mempunyai kod yang ingin kami jalankan dalam semua situasi, akhirnya-block ialah lelaki kami. Blok ini kebanyakannya digunakan untuk pembersihan seperti menutup fail.
Pertimbangkan contoh kod Python di bawah
def readFile(file_path): try: openFile = open(file_path,'r') # Open a file as read-only print(openFile.readline()) # Read first line of file content except FileNotFoundError as ex: print(ex) finally: print("Cleaning...") openFile.close() if __name__ == '__main__': filePath = './text.txt' readFile(filePath)
Kod ini cuba membuka dan membaca fail text.txt dalam direktori semasanya. Jika fail itu wujud, maka atur cara kami akan mencetak baris pertama fail kemudian blok akhirnya kami akan berjalan dan menutup fail.
Katakan kami mempunyai fail bernama text.txt dalam direktori tempat fail atur cara ini adalah dan mengandungi Hello. Jika kita menjalankan program, kita akan mempunyai output
Contoh ini dipilih dengan sengaja kerana saya mahu kita menangani masalah kecil yang mungkin berlaku apabila menutup fail dalam akhirnya- blok.
Jika fail tidak wujud, pengecualian FileNotFoundError akan dinaikkan dan pembolehubah openFile tidak akan ditakrifkan dan bukan fail objek. Oleh itu, cubaan menutupnya dalam blok akhirnya akan menimbulkan pengecualian UnboundLocalError yang merupakan subkelas NameError .
Ini pada asasnya mengatakan bahawa kami cuba merujuk yang