Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Industrial programming >> Python

Menghindari Jebakan Umum: Penanganan Eksepsi yang Benar dalam Python

Menghindari Jebakan Umum: Penanganan Eksepsi yang Benar dalam Python

Saya melihat banyak orang menangani eksepsi dengan cara yang salah. Mungkin ini berlaku untuk Anda juga. Apakah situasi berikut terdengar familiar?

Anda sedang menulis beberapa kode, dan Anda tahu bahwa perpustakaan yang Anda gunakan mungkin memunculkan eksepsi. Anda tidak ingat eksepsi mana, tepatnya. Pada titik ini, menggoda untuk menggunakan blok catch-all dan melanjutkan dengan hal-hal menyenangkan.

Daftar isi

Cara terburuk untuk melakukannya

Yang terburuk yang bisa Anda lakukan adalah membuat blok try-except yang menangkap apa pun. Dengan catch-all, saya maksud sesuatu seperti:

try: ... except: pass

Blok catch-all semacam ini buruk karena:

  1. Anda tidak tahu eksepsi lain apa yang mungkin muncul (selengkapnya nanti).
  2. Kami menyembunyikan eksepsi dengan menggunakan pass secara diam-diam alih-alih mencatat kesalahan.

Selain itu, except kosong akan menangkap semuanya, termasuk KeyboardInterrupt (control + c), SystemExit, dan bahkan NameErrors! Ini berarti kode berikut tidak dapat dihentikan secara bersih:

from time import sleep while True: try: print("Try and stop me") sleep(1) except: print("Don't.. stop.. me now!")

Silakan coba. Anda perlu menutup jendela terminal atau membunuh proses Python untuk menghentikan program ini.

Cara yang cukup baik untuk menangkap semua eksepsi

Di sisi lain, saat menggunakan except Exception, meskipun masih merupakan cara cepat dan kotor untuk menangkap terlalu banyak eksepsi, setidaknya Anda akan dapat menghentikan proses yang berjalan dengan benar:

from time import sleep while True: try: print("Try and stop me") sleep(1) except Exception: print("Ok I'll stop!")

Saat menangkap Exception Anda tidak akan menangkap SystemExit, KeyboardInterrupt dan eksepsi semacam itu. Mengapa demikian, Anda tanya?

Semua eksepsi berasal dari kelas yang disebut BaseException. Menurut dokumentasi resmi: “Dalam pernyataan try dengan klausa except yang menyebut kelas tertentu, klausa tersebut juga menangani kelas eksepsi yang berasal dari kelas tersebut.” Except kosong setara dengan except BaseException, oleh karena itu akan menangkap semua eksepsi yang mungkin.

Di sisi lain, kelas Exception didefinisikan sebagai: “Semua eksepsi bawaan, non-sistem-keluar berasal dari kelas ini. Semua eksepsi yang didefinisikan pengguna juga harus berasal dari kelas ini.”

Itu menjadi lebih buruk

Dalam contoh berikut, kami menggunakan perpustakaan os untuk mendapatkan direktori kerja saat ini. Namun, jari-jari gemuk saya membuat kesalahan ketik:

import os try: working_dir = os.getcdw() print(working_dir) except: print('error')

Karena os.getcdw bukan fungsi dalam modul os, NameError dilemparkan. Alih-alih gagal, klausa except akan menangkap kesalahan, mencetak ‘error’ dan program akan terus berjalan meskipun kesalahan ketik yang jelas kita lakukan. Sayangnya, ini tidak dapat diselesaikan dengan menangkap Exception juga!

Sepertinya, trik kecil kami dari langkah satu bukan solusi untuk semua masalah kami. Jadi apa yang harus kita lakukan?

Tangkap apa yang dapat Anda tangani

Sebuah frasa yang sering didengar tentang eksepsi adalah: tangkap apa yang dapat Anda tangani. Banyak pengembang tertarik untuk langsung menangani eksepsi, sementara seringkali lebih baik untuk membiarkan eksepsi menyebar ke bagian program Anda yang sebenarnya dapat menanganinya.

Misalnya, pertimbangkan bagian editor teks yang membuka dan memuat file, mari kita sebut kelas OpenFile. Jika pengguna meminta membuka file yang tidak ada, Anda dapat langsung menangani kesalahan itu, atau membiarkannya menyebar.

Dalam kasus ini, lebih baik untuk menyebarkan eksepsi ke pemanggil, karena OpenFile tidak tahu seberapa buruk eksepsi ini bagi pemanggil. Pemanggil dapat menangani situasi dengan beberapa cara:

Apapun caranya, bukan tanggung jawab kelas OpenFile untuk memutuskan apa yang harus dilakukan dalam kasus FileNotFoundError.

Jadi apakah eksepsi harus selalu menyebar? Tidak. Eksepsi yang mungkin dapat ditangani dalam kelas FileOpen adalah TimeoutError. Anda mungkin ingin mencoba beberapa kali, misalnya, tanpa mengganggu pemanggil dengan kesalahan. Ini adalah eksepsi yang dapat ditangani oleh OpenFile, jadi tidak apa-apa untuk menangkapnya dan mencoba lagi.

Kesimpulan

Anda tidak boleh dalam keadaan apa pun menangkap lebih banyak eksepsi daripada yang dapat Anda tangani. Blok except umum adalah resep untuk bug dan kode yang tidak dapat diprediksi. Dengan kata lain: tangkap apa yang dapat Anda tangani.

Jika Anda menulis kode Anda dengan matra ‘tangkap apa yang dapat Anda tangani’ dalam pikiran, menulis blok catch-all adalah melanggar semua aturan. Jadi tolong, hentikan itu. Sebagai latihan, Anda dapat memeriksa beberapa kode yang ada Anda dan melihat apakah dapat diperbaiki dengan pengetahuan baru ini!


Python

  1. Menguasai Operator Python: Panduan Komprehensif
  2. Menguasai Error dan Exception Bawaan Python
  3. Menguasai Exception Kustom Python: Panduan Praktis
  4. Mengambil Tanggal dan Waktu Saat Ini di Python: Panduan Praktis
  5. Menguasai Penanganan Multi-Pengecualian di Java
  6. Menguasai Pelatihan CMMS: Melibatkan Tim dan Meningkatkan Retensi
  7. Fungsi print() Python: Panduan Praktis dengan Contoh
  8. Kamus Python: Menambahkan, Memperbarui, dan Mengelola Pasangan Kunci/Nilai
  9. Python Print Tanpa Baris Baru: Menguasai Parameter end & Teknik Lainnya
  10. Menghitung Rata-rata di Python: Panduan Praktis