Saya memiliki fungsi yang dipanggil oleh program utama:
try:
someFunction()
except:
print "exception happened!"
tetapi di tengah pelaksanaan fungsi itu menimbulkan pengecualian, sehingga melompat ke except
bagian tersebut.
Bagaimana saya bisa melihat dengan tepat apa yang terjadi di dalam someFunction()
yang menyebabkan pengecualian terjadi?
except:
(tanpa bareraise
), kecuali mungkin sekali per program, dan lebih baik tidak melakukannya.except
klausa, Anda tidak perlu memeriksa jenis pengecualian, itulah yang biasanya dilakukan untuk bertindak sesuai dengan jenis pengecualian tertentu.except
blok pengecualian tersedia melaluisys.exc_info()
fungsi - fungsi ini mengembalikan tuple dari tiga nilai yang memberikan informasi tentang pengecualian yang saat ini sedang ditangani.Jawaban:
Semua jawaban lainnya menunjukkan bahwa Anda tidak boleh menangkap pengecualian umum, tetapi tampaknya tidak ada yang mau memberi tahu Anda alasannya, yang penting untuk dipahami ketika Anda dapat melanggar "aturan". Berikut ini penjelasannya. Pada dasarnya, agar Anda tidak menyembunyikan:
Jadi selama Anda berhati-hati untuk tidak melakukan hal-hal itu, tidak apa-apa untuk menangkap pengecualian umum. Misalnya, Anda dapat memberikan informasi tentang pengecualian kepada pengguna dengan cara lain, seperti:
Jadi bagaimana cara menangkap pengecualian umum? Ada beberapa cara. Jika Anda hanya ingin objek pengecualian, lakukan seperti ini:
Membuat yakin
message
dibawa ke perhatian pengguna dalam cara yang sulit untuk miss! Mencetaknya, seperti yang ditunjukkan di atas, mungkin tidak cukup jika pesan terkubur dalam banyak pesan lainnya. Gagal mendapatkan perhatian pengguna sama saja dengan menelan semua pengecualian, dan jika ada satu kesan yang seharusnya Anda dapatkan setelah membaca jawaban di halaman ini, itu karena ini bukan hal yang baik . Mengakhiri kecuali blok dengan araise
pernyataan akan memperbaiki masalah dengan secara transparan mengembalikan pengecualian yang tertangkap.Perbedaan antara di atas dan menggunakan hanya
except:
tanpa argumen ada dua:except:
tidak memberi Anda objek pengecualian untuk diperiksaSystemExit
,KeyboardInterrupt
danGeneratorExit
tidak ditangkap oleh kode di atas, yang umumnya Anda inginkan. Lihat hierarki pengecualian .Jika Anda juga ingin stacktrace yang sama dengan yang Anda dapatkan jika Anda tidak menangkap pengecualian, Anda bisa mendapatkan yang seperti ini (masih di dalam klausa kecuali):
Jika Anda menggunakan
logging
modul, Anda dapat mencetak pengecualian ke log (bersama dengan pesan) seperti ini:Jika Anda ingin menggali lebih dalam dan memeriksa tumpukan, lihat variabel dll, gunakan
post_mortem
fungsipdb
modul di dalam blok kecuali:Saya menemukan metode terakhir ini sangat berharga ketika memburu bug.
sumber
Dapatkan nama kelas yang dimiliki objek pengecualian:
dan menggunakan fungsi print_exc () juga akan mencetak jejak tumpukan yang merupakan info penting untuk pesan kesalahan apa pun.
Seperti ini:
Anda akan mendapatkan output seperti ini:
Dan setelah dicetak dan dianalisis, kode dapat memutuskan untuk tidak menangani pengecualian dan hanya menjalankan
raise
:Keluaran:
Dan interpreter mencetak pengecualian:
Setelah
raise
pengecualian asli terus menyebar lebih jauh ke tumpukan panggilan. ( Waspadai kemungkinan jebakan ) Jika Anda meningkatkan pengecualian baru, ia mencari jejak tumpukan yang lebih pendek.Keluaran:
Perhatikan bagaimana traceback tidak menyertakan
calculate()
fungsi dari garis9
yang merupakan asal dari pengecualian aslie
.sumber
traceback.format_exc()
jugae.__class__.__name__
apakah ini sama dengantype(e).__name__
, seperti yang disarankan oleh jawaban di atas?Anda biasanya tidak boleh menangkap semua pengecualian yang mungkin terjadi
try: ... except
karena ini terlalu luas. Hanya menangkap mereka yang diharapkan terjadi karena alasan apa pun. Jika Anda benar-benar harus, misalnya jika Anda ingin mengetahui lebih lanjut tentang beberapa masalah saat debugging, Anda harus melakukannyasumber
try: ... except Exception:
banyak hal, misalnya penggunaan perpustakaan yang tergantung pada jaringan, atau pemijat data yang mungkin mengirim barang aneh kepadanya. Secara alami saya juga memiliki logging yang benar. Ini sangat penting untuk memungkinkan program untuk terus beroperasi jika ada kesalahan tunggal dalam input data.smtplib
?Kecuali jika
somefunction
fungsi warisan kode yang sangat buruk, Anda seharusnya tidak memerlukan apa yang Anda minta.Gunakan beberapa
except
klausa untuk menangani dengan cara yang berbeda pengecualian berbeda:Poin utama adalah bahwa Anda tidak harus menangkap pengecualian umum, tetapi hanya yang perlu. Saya yakin Anda tidak ingin membayangi kesalahan atau bug yang tidak terduga.
sumber
Sebagian besar jawaban menunjuk ke
except (…) as (…):
sintaks (memang demikian) tetapi pada saat yang sama tidak ada yang ingin berbicara tentang gajah di dalam ruangan, di mana gajahsys.exc_info()
berfungsi. Dari dokumentasi dari sys modul (penekanan):Saya pikir yang
sys.exc_info()
bisa diperlakukan sebagai jawaban paling langsung untuk pertanyaan awal dari Bagaimana saya tahu jenis pengecualian apa yang terjadi?sumber
except
. Hanya demi kelengkapan,exctype, value = sys.exc_info()[:2]
akan memberi tahu Anda jenis pengecualian yang kemudian dapat digunakan di Internetexcept
.coba: someFunction () kecuali Exception, exc:
sumber
exc.__class__.__name__
telah disarankan dalam jawaban Alex - stackoverflow.com/a/9824060/95735Jawaban-jawaban ini baik untuk debugging, tetapi untuk pemrograman pengecualian,
isinstance(e, SomeException)
bisa berguna, karena juga menguji subclassSomeException
, sehingga Anda dapat membuat fungsionalitas yang berlaku untuk hierarki pengecualian.sumber
Begini cara saya menangani pengecualian saya. Idenya adalah untuk mencoba menyelesaikan masalah jika itu mudah, dan kemudian tambahkan solusi yang lebih diinginkan jika memungkinkan. Jangan memecahkan masalah dalam kode yang menghasilkan pengecualian, atau bahwa kode kehilangan jejak dari algoritma asli, yang harus ditulis to-the-point. Namun, sampaikan data apa yang diperlukan untuk menyelesaikan masalah ini, dan kembalikan lambda jika Anda tidak dapat memecahkan masalah di luar kode yang menghasilkannya.
Untuk saat ini, karena saya tidak ingin berpikir secara berlawanan dengan tujuan aplikasi saya, saya belum menambahkan solusi yang rumit. Tetapi di masa depan, ketika saya tahu lebih banyak tentang solusi yang mungkin (karena aplikasi ini dirancang lebih), saya bisa menambahkan kamus solusi yang diindeks oleh
during
.Dalam contoh yang ditunjukkan, satu solusi mungkin untuk mencari data aplikasi yang disimpan di tempat lain, katakanlah jika file 'app.p' terhapus secara tidak sengaja.
Untuk saat ini, karena menulis handler pengecualian bukanlah ide yang cerdas (kami belum tahu cara terbaik untuk menyelesaikannya, karena desain aplikasi akan berkembang), kami cukup mengembalikan perbaikan mudah yang bertindak seperti sedang berjalan aplikasi untuk pertama kalinya (dalam hal ini).
sumber
Untuk menambah jawaban Lauritz, saya membuat dekorator / pembungkus untuk penanganan pengecualian dan log pembungkus yang jenis pengecualian terjadi.
Ini dapat dipanggil pada metode kelas atau fungsi mandiri dengan dekorator:
@general_function_handler
Lihat blog saya tentang untuk contoh lengkap: http://ryaneirwin.wordpress.com/2014/05/31/python-decorators-and-exception-handling/
sumber
Anda bisa mulai seperti yang direkomendasikan Lauritz, dengan:
dan kemudian
print ex
seperti itu:sumber
Pengecualian aktual dapat ditangkap dengan cara berikut:
Anda dapat mempelajari lebih lanjut tentang pengecualian dari Tutorial Python .
sumber
Pertanyaan Anda adalah: "Bagaimana saya bisa melihat dengan tepat apa yang terjadi pada fungsi tertentu () yang menyebabkan pengecualian terjadi?"
Tampak bagi saya bahwa Anda tidak bertanya tentang bagaimana menangani pengecualian yang tidak terduga dalam kode produksi (seperti yang diasumsikan oleh banyak jawaban), tetapi bagaimana mencari tahu apa yang menyebabkan pengecualian tertentu selama pengembangan.
Cara termudah adalah dengan menggunakan debugger yang bisa berhenti ketika pengecualian yang tidak tertangkap terjadi, lebih disukai tidak keluar, sehingga Anda dapat memeriksa variabel. Sebagai contoh, PyDev di IDE open source Eclipse dapat melakukan itu. Untuk mengaktifkannya di Eclipse, buka perspektif Debug, pilih
Manage Python Exception Breakpoints
diRun
menu, dan centangSuspend on uncaught exceptions
.sumber
Hanya menahan diri dari menangkap pengecualian dan traceback yang dicetak Python akan memberi tahu Anda apa yang terjadi pengecualian.
sumber