Bagaimana cara mendapatkan nama pengecualian yang ditangkap dengan Python?

122

Bagaimana saya bisa mendapatkan nama pengecualian yang dimunculkan dengan Python?

misalnya,

try:
    foo = bar
except Exception as exception:
    name_of_exception = ???
    assert name_of_exception == 'NameError'
    print "Failed with exception [%s]" % name_of_exception

Misalnya, saya menangkap beberapa (atau semua) pengecualian, dan ingin mencetak nama pengecualian tersebut dalam pesan kesalahan.

Rob Bednark
sumber
3
Mengapa Anda pikir Anda perlu ini? Mengapa tidak menangkap pengecualian yang lebih konkret (misalnya except NameError:) untuk memulai?
7
Saya memiliki beberapa skenario di mana saya ingin menangkap semua pengecualian (atau daftar dari mereka), dan ingin mencetak nama pengecualian dalam pesan kesalahan.
Rob Bednark
1
Anda mungkin ingin memeriksa tracebackmodul pustaka standar , yang memiliki fungsi yang melakukan beberapa pemformatan bagus untuk pengecualian dan pelacakan ulang.
Blckknght
1
@delnan situasi ini muncul saat Anda menguji apakah suatu fungsi memunculkan pengecualian seperti yang diprogram
gokul_uf
Saya membutuhkan sesuatu seperti ini untuk MENGERINGKAN beberapa kode: beberapa pengecualian dapat dimunculkan oleh metode yang saya panggil, masing-masing ditangani dengan exceptpernyataan mereka sendiri , tetapi entri log sangat mirip dalam setiap kasus.
Adam Carroll

Jawaban:

224

Berikut adalah beberapa cara berbeda untuk mendapatkan nama kelas dari pengecualian:

  1. type(exception).__name__
  2. exception.__class__.__name__
  3. exception.__class__.__qualname__

misalnya,

try:
    foo = bar
except Exception as exception:
    assert type(exception).__name__ == 'NameError'
    assert exception.__class__.__name__ == 'NameError'
    assert exception.__class__.__qualname__ == 'NameError'
pengguna1234
sumber
6

Ini berfungsi, tetapi sepertinya pasti ada cara yang lebih mudah dan langsung?

try:
    foo = bar
except Exception as exception:
    assert repr(exception) == '''NameError("name 'bar' is not defined",)'''
    name = repr(exception).split('(')[0]
    assert name == 'NameError'
Rob Bednark
sumber
4
Ganti except Exception as exceptiondengan jenis pengecualian yang ingin Anda tangkap, yaitu except NameError as exception.
Maciej Gol
8
Saya tidak ingin menangkap pengecualian tertentu yang diketahui sebelumnya. Saya ingin menangkap semua pengecualian.
Rob Bednark
3

Anda juga bisa menggunakan sys.exc_info(). exc_info()mengembalikan 3 nilai: type, value, traceback. Tentang dokumentasi: https://docs.python.org/3/library/sys.html#sys.exc_info

import sys

try:
    foo = bar
except Exception:
    exc_type, value, traceback = sys.exc_info()
    assert exc_type.__name__ == 'NameError'
    print "Failed with exception [%s]" % exc_type.__name__
moshfiqur.dll
sumber
1

Jika Anda menginginkan nama kelas yang sepenuhnya memenuhi syarat (misalnya, sqlalchemy.exc.IntegrityErrorbukan hanya IntegrityError), Anda dapat menggunakan fungsi di bawah ini, yang saya ambil dari jawaban MB yang luar biasa untuk pertanyaan lain (saya baru saja mengganti nama beberapa variabel agar sesuai dengan selera saya):

def get_full_class_name(obj):
    module = obj.__class__.__module__
    if module is None or module == str.__class__.__module__:
        return obj.__class__.__name__
    return module + '.' + obj.__class__.__name__

Contoh:

try:
    # <do something with sqlalchemy that angers the database>
except sqlalchemy.exc.SQLAlchemyError as e:
    print(get_full_class_name(e))

# sqlalchemy.exc.IntegrityError
MarredCheese
sumber
0

Jawaban lain di sini bagus untuk tujuan eksplorasi, tetapi jika tujuan utamanya adalah mencatat pengecualian (termasuk nama pengecualian), mungkin pertimbangkan untuk menggunakan logging.exception daripada print?

MrName
sumber