Bagaimana cara mencetak pengecualian dengan Python?

Jawaban:

1063

Untuk Python 2.6 dan yang lebih baru dan Python 3.x:

except Exception as e: print(e)

Untuk Python 2.5 dan sebelumnya, gunakan:

except Exception,e: print str(e)
jldupont
sumber
41
str( KeyError('bad'))=> 'bad'- tidak memberi tahu tipe pengecualian
Dave
10
cetak (e) pada keyerrors tampaknya hanya memberikan kunci, tetapi bukan pesan pengecualian penuh, yang kurang bermanfaat.
Veggiet
14
Jika Anda ingin mencetak pengecualian, lebih baik digunakan print(repr(e)); Exception.__str__implementasi basis hanya mengembalikan pesan pengecualian, bukan tipe. Atau, gunakan tracebackmodul, yang memiliki metode untuk mencetak pengecualian saat ini, diformat, atau traceback penuh.
Martijn Pieters
453

The tracebackModul menyediakan metode untuk memformat dan mencetak pengecualian dan tracebacks mereka, misalnya ini akan mencetak pengecualian seperti penangan default tidak:

import traceback

try:
    1/0
except Exception:
    traceback.print_exc()

Keluaran:

Traceback (most recent call last):
  File "C:\scripts\divide_by_zero.py", line 4, in <module>
    1/0
ZeroDivisionError: division by zero
Cat Plus Plus
sumber
4
apakah ada semacam panggilan get_error_message yang dapat saya cetak dengan melihat karena saya menggunakan rutin pencetakan saya sendiri untuk menambahkan beberapa hal lain.
MikeSchem
11
@MikeSchem error_message = traceback.format_exc()
heyzling
3
Terima kasih, ini yang saya inginkan. Seluruh jejak, bukan hanya tipe dan pesan kesalahan
Ken Bellows
Potongan ini tidak menggunakan objek pengecualian yang diambil. Bisakah Anda memperluas kode untuk menggunakan 'mantan'? - seperti di except Exception as ex:...
aaronsteers
@ aaronsteers menggunakan pengecualian yang ditangkap; dalam handler pengecualian pengecualian saat ini tersedia melalui sys.exc_info()fungsi dan traceback.print_exc()fungsi mendapatkannya dari sana. Anda hanya perlu menyampaikan pengecualian secara eksplisit saat tidak menangani pengecualian atau ketika Anda ingin menampilkan info berdasarkan pengecualian yang berbeda.
Martijn Pieters
169

Dalam Python 2.6 atau lebih besar itu sedikit lebih bersih:

except Exception as e: print(e)

Dalam versi yang lebih lama masih cukup mudah dibaca:

except Exception, e: print e
ilya n.
sumber
15
Di python3, harus menggunakan cara 1, dengan "sebagai".
Sam Watkins
53

Jika Anda ingin meneruskan string kesalahan, berikut adalah contoh dari Kesalahan dan Pengecualian (Python 2.6)

>>> try:
...    raise Exception('spam', 'eggs')
... except Exception as inst:
...    print type(inst)     # the exception instance
...    print inst.args      # arguments stored in .args
...    print inst           # __str__ allows args to printed directly
...    x, y = inst          # __getitem__ allows args to be unpacked directly
...    print 'x =', x
...    print 'y =', y
...
<type 'exceptions.Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
Nick Dandoulakis
sumber
38

(Saya akan meninggalkan ini sebagai komentar pada jawaban @ jldupont, tetapi saya tidak memiliki reputasi yang cukup.)

Saya telah melihat jawaban seperti jawaban @ jldupont di tempat lain juga. FWIW, saya pikir penting untuk dicatat bahwa ini:

except Exception as e:
    print(e)

akan mencetak output kesalahan sys.stdoutsecara default. Pendekatan yang lebih tepat untuk penanganan kesalahan secara umum adalah:

except Exception as e:
    print(e, file=sys.stderr)

(Perhatikan bahwa Anda harus melakukan import sysini agar berfungsi.) Dengan cara ini, kesalahan dicetak STDERRbukan STDOUT, yang memungkinkan penguraian / redirection / etc keluaran yang tepat. Saya mengerti bahwa pertanyaannya adalah tentang 'mencetak kesalahan', tetapi tampaknya penting untuk menunjukkan praktik terbaik di sini daripada mengabaikan detail ini yang dapat mengarah pada kode non-standar bagi siapa saja yang pada akhirnya tidak belajar lebih baik.

Saya belum menggunakan tracebackmodul seperti pada jawaban Cat Plus Plus, dan mungkin itu cara terbaik, tapi saya pikir saya akan membuang ini di sana.

grish
sumber
1
Saya akan menyarankan lebih lanjut menambahkan flush = True. Saya perhatikan dengan systemd (dan tidak menggunakan kerangka logging yang tepat), bahwa buffering ketika menangkap ke jurnal bukanlah yang saya harapkan.
Cameron Kerr
20

Python 3: logging

Alih-alih menggunakan print()fungsi dasar , loggingmodul yang lebih fleksibel dapat digunakan untuk mencatat pengecualian. The loggingModul menawarkan banyak fungsi tambahan, pesan penebangan misalnya ke dalam sebuah file log yang diberikan, penebangan pesan dengan cap waktu dan informasi tambahan tentang di mana penebangan terjadi. (Untuk informasi lebih lanjut, lihat dokumentasi resmi .)

Mencatat pengecualian dapat dilakukan dengan fungsi tingkat modul logging.exception()seperti:

import logging

try:
    1/0
except BaseException:
    logging.exception("An exception was thrown!")

Keluaran:

ERROR:root:An exception was thrown!
Traceback (most recent call last):
  File ".../Desktop/test.py", line 4, in <module>
    1/0
ZeroDivisionError: division by zero 

Catatan:

  • fungsi logging.exception()hanya dapat dipanggil dari handler pengecualian

  • yang loggingmodul tidak boleh digunakan dalam penangan logging untuk menghindari RecursionError(terima kasih @PrakharPandey)


Tingkat log alternatif

Dimungkinkan juga untuk mencatat pengecualian dengan tingkat log lain dengan menggunakan argumen kata kunci exc_info=Trueseperti:

logging.debug("An exception was thrown!", exc_info=True)
logging.info("An exception was thrown!", exc_info=True)
logging.warning("An exception was thrown!", exc_info=True)
winklerrr
sumber
1
Seharusnya tidak digunakan di dalam handler logging untuk menghindari RecursionError
Prakhar Pandey
4

Peningkatan kesalahan satu liner dapat dilakukan dengan pernyataan pernyataan jika itu yang ingin Anda lakukan. Ini akan membantu Anda menulis kode yang dapat diperbaiki secara statis dan memeriksa kesalahan lebih awal.

assert type(A) is type(""), "requires a string"
ada apa
sumber
2

Seseorang memiliki cukup banyak kontrol di mana informasi dari traceback akan ditampilkan / dicatat ketika menangkap pengecualian.

Kode

with open("not_existing_file.txt", 'r') as text:
    pass

akan menghasilkan traceback berikut:

Traceback (most recent call last):
  File "exception_checks.py", line 19, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Cetak / Log traceback penuh

Seperti yang telah disebutkan orang lain, Anda dapat menangkap seluruh traceback dengan menggunakan modul traceback:

import traceback
try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    traceback.print_exc()

Ini akan menghasilkan output berikut:

Traceback (most recent call last):
  File "exception_checks.py", line 19, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Anda dapat mencapai hal yang sama dengan menggunakan pendataan:

try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    logger.error(exception, exc_info=True)

Keluaran:

__main__: 2020-05-27 12:10:47-ERROR- [Errno 2] No such file or directory: 'not_existing_file.txt'
Traceback (most recent call last):
  File "exception_checks.py", line 27, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Cetak / catat nama kesalahan / pesan saja

Anda mungkin tidak tertarik dengan traceback secara keseluruhan, tetapi hanya pada informasi yang paling penting, seperti nama Exception dan pesan Exception, gunakan:

try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    print("Exception: {}".format(type(exception).__name__))
    print("Exception message: {}".format(exception))

Keluaran:

Exception: FileNotFoundError
Exception message: [Errno 2] No such file or directory: 'not_existing_file.txt'
GinTonic
sumber