Mendapatkan nilai pengecualian dengan Python

239

Jika saya memiliki kode itu:

try:
    some_method()
except Exception, e:

Bagaimana saya bisa mendapatkan nilai Pengecualian ini (representasi string yang saya maksud)?

Frias
sumber

Jawaban:

323

menggunakan str

try:
    some_method()
except Exception as e:
    s = str(e)

Selain itu, sebagian besar kelas pengecualian akan memiliki argsatribut. Seringkali, args[0]akan ada pesan kesalahan.

Perlu dicatat bahwa hanya menggunakan strakan mengembalikan string kosong jika tidak ada pesan kesalahan sedangkan menggunakan reprsebagai pyfunc merekomendasikan setidaknya akan menampilkan kelas pengecualian. Menurut saya, jika Anda mencetaknya, itu untuk pengguna akhir yang tidak peduli apa kelasnya dan hanya menginginkan pesan kesalahan.

Ini benar-benar tergantung pada kelas pengecualian yang Anda hadapi dan bagaimana instantiated. Apakah Anda memiliki sesuatu yang khusus dalam pikiran?

aaronasterling
sumber
Saya mencetak ini untuk membuat laporan, str (e) baik-baik saja kurasa. Terima kasih banyak
Frias
8
Saya lebih suka menggunakan e.messagekarena args[0]mungkin sebenarnya bukan pesan.
cedbeu
3
repr (e) juga membantu jika Anda ingin mendapatkan pengecualian penuh (mis. NameError ("variabel nama global 'tidak didefinisikan",), alih-alih "variabel nama global' tidak didefinisikan"
Ben Morris
49
jawaban ini berbahaya, karena akan gagal untuk pengecualian unicode seperti ini: raise Exception(u'jörn'). Kegagalan itu terutama buruk, karena Anda tidak akan pernah melihat pengecualian aktual tetapi hanya a UnicodeDecodeError. Jika Anda tidak tahu pengkodean pengecualian (dan sebagian besar waktu Anda tidak), Anda harus bekerja pada repr(e)atau jika Anda benar-benar perlu, gunakan blok coba-kecuali lain dalam penanganan pengecualian Anda yang menangkap UnicodeDecodeErrors dan jatuh kembali ke repr(e).
Jörn Hees
11
Setuju dengan @ JörnHees. Saya tidak dapat menghitung berapa kali str(atau bahkan unicodeatau .format) telah menyebabkan bug karena penanganan Unicode. Jika Anda tidak memiliki kendali penuh atas isi pesan kesalahan, SELALU gunakan repruntuk menghindari kesalahan Unicode yang tidak terduga.
Kenny Trytek
186

Gunakan repr () dan Perbedaan antara menggunakan repr dan str

Menggunakan repr:

>>> try:
...     print(x)
... except Exception as e:
...     print(repr(e))
... 
NameError("name 'x' is not defined")

Menggunakan str:

>>> try:
...     print(x)
... except Exception as e:
...     print(str(e))
... 
name 'x' is not defined
pyfunc
sumber
2
ah, reprini berkat berguna, tampaknya apa pun unicode, str, encoding, ... mungkin meningkatkan pengecualian tergantung pada masukan. Tidak cukup berguna ketika mencoba untuk menjaga pengecualian untuk melihat, tetapi repr exception-safetampaknya
dashesy
2
Ini jauh lebih baik daripada str()solusi seperti apa pun , karena itu sebenarnya termasuk jenis pengecualian. Dengan str()saya 'status'sementara repr()saya KeyError('status')dan saya seperti "aaaaah, sekarang saya mengerti kesalahan".
jlh
27

Meskipun saya menyadari ini adalah pertanyaan lama, saya ingin menyarankan menggunakan tracebackmodul untuk menangani output dari pengecualian.

Gunakan traceback.print_exc()untuk mencetak pengecualian saat ini ke kesalahan standar, sama seperti itu akan dicetak jika tetap tidak tertangkap, atau traceback.format_exc()untuk mendapatkan hasil yang sama seperti string. Anda dapat meneruskan berbagai argumen ke salah satu fungsi tersebut jika Anda ingin membatasi output, atau mengalihkan pencetakan ke objek seperti file.

Blckknght
sumber
23

Cara lain belum diberikan:

try:
    1/0
except Exception, e:
    print e.message

Keluaran:

integer division or modulo by zero

args[0] mungkin sebenarnya bukan pesan.

str(e)mungkin mengembalikan string dengan tanda kutip yang mengelilinginya dan mungkin dengan yang utama ujika unicode:

'integer division or modulo by zero'

repr(e) memberikan representasi pengecualian penuh yang mungkin bukan yang Anda inginkan:

"ZeroDivisionError('integer division or modulo by zero',)"

sunting

Salahku !!! Tampaknya BaseException.message sudah tidak digunakan lagi2.6 , akhirnya, tampaknya masih belum ada cara standar untuk menampilkan pesan pengecualian. Jadi saya kira yang terbaik adalah melakukan berurusan dengan e.argsdan str(e)tergantung pada kebutuhan Anda (dan mungkin e.messagejika lib yang Anda gunakan bergantung pada mekanisme itu).

Misalnya, dengan pygraphviz, e.messageadalah satu-satunya cara untuk menampilkan dengan benar pengecualian, menggunakan str(e)akan mengelilingi pesan u''.

Tetapi dengan MySQLdb, cara yang tepat untuk mengambil pesan adalah e.args[1]: e.messagekosong, dan str(e)akan ditampilkan'(ERR_CODE, "ERR_MSG")'

cedbeu
sumber
0

Untuk python2, Lebih baik digunakan e.messageuntuk mendapatkan pesan pengecualian, ini akan menghindari kemungkinan UnicodeDecodeError. Tapi ya e.messageakan kosong untuk beberapa jenis pengecualian seperti OSError, dalam hal ini kita dapat menambahkan exc_info=Truefungsi logging kita untuk tidak melewatkan kesalahan.
Untuk python3, saya pikir aman untuk digunakan str(e).

apporc
sumber
0

Jika Anda tidak tahu jenis / asal kesalahan, Anda dapat mencoba:

import sys
try:
    doSomethingWrongHere()
except:
    print('Error: {}'.format(sys.exc_info()[0]))

Namun perlu diperhatikan, Anda akan mendapatkan peringatan:

[W] PEP 8 (E722): do not use bare except
Kostano
sumber
0

Untuk memeriksa pesan kesalahan dan melakukan sesuatu dengannya (dengan Python 3) ...

try:
    some_method()
except Exception as e:
    if {value} in e.args:
        {do something}
DanGoodrick
sumber