Подтвердить что ты не робот

Как удалить "__main__". с начала созданных пользователем классов исключений в Python

Есть ли способ получить "более красивое" исключение, а не одно с __main__MyExceptionTitle?

Пример:

>>> class BadThings(Exception):
...     def __init__(self, msg):
...         self.msg = msg
...         return
... 
>>> class BadThings(Exception):
...     def __init__(self, msg):
...         self.msg = msg
...         return
...     def __str__(self):
...         return self.msg
... 
>>> raise BadThings("This is really, really bad")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.BadThings: This is really, really bad

Хотелось бы просто сказать:

BadThings: Это действительно, очень плохо

Точно так же, как если бы один тип:

>>> raise Exception("This, too, is really, really bad")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: This, too, is really, really bad

Мне нужен __main__. пошел!

Спасибо, Narnie

4b9b3361

Ответ 1

Я не уверен, почему вы хотите удалить __main__, потому что это имя модуля и когда ваше исключение будет в соответствующем именованном модуле, оно выглядело бы красивым, а не уродливым, например. myexceptions.BadException

В качестве альтернативы вы можете ловить исключение и печатать, как хотите.

Но если вы хотите, чтобы неперехваченные исключения печатались в соответствии с вашим желанием, попробуйте установить sys.excepthook например.

class BadThings(Exception): pass 

import traceback
def myexcepthook(type, value, tb):
    l = ''.join(traceback.format_exception(type, value, tb))
    print l

import sys
sys.excepthook = myexcepthook

raise BadThings("bad bad")

Вывод:

Traceback (most recent call last):
  File "untitled-1.py", line 12, in <module>
    raise BadThings("bad bad")
BadThings: bad bad

Итак, в sys.excepthook вы можете изменить исключение, отформатировать его и т.д.

Ответ 2

class MyException( Exception ):
    __module__ = Exception.__module__

Этот способ выглядит/работает лучше, чем sys.excepthook


Ссылка на исходный код

python2

См. PyErr_Display

Существует два способа обойти часть имени модуля:

class A( Exception ):
    __module__ = None

class B( Exception ):
    __module__ = 'exceptions'

Но если вам нужно сыграть с threading.Thread, первая представит TypeError.

Python 3

См. PyErr_WriteUnraisable

Работает только второй способ. Используйте builtins вместо exceptions.

Ответ 3

Если вы обрабатываете исключение, вы можете отформатировать сообщение любым способом:

>>> try:
...     raise BadThings("This is really, really bad")
... except BadThings, e:
...     print e.msg
... 
This is really, really bad

Ответ 4

Это небольшая модификация ответа @Anurag.

Если вы хотите избавиться от __main__. И трассировки, вы можете сделать что-то вроде этого:

import sys
import traceback

class BadThings(Exception):
    def myexcepthook(type, value, tb):
        msg = ''.join(traceback.format_exception_only(type, value))
        print(msg)

    sys.excepthook = myexcepthook

raise BadThings("This is really, really bad")

Вывод:

BadThings: This is really, really bad

Дополнительным преимуществом определения sys.excepthook в классе исключений является то, что он не будет отменять все исключения, просто BadThings.