Распечатайте иерархию исключений/ошибок Python

Является ли какой-либо параметр командной строки в python для печати иерархии классов исключений/ошибок?

Выход должен быть похож на http://docs.python.org/2/library/exceptions.html#exception-hierarchy

Ответ 1

inspect может помочь, в частности getclasstree():

Упорядочить данный список классов в иерархию вложенных списков. Когда появляется вложенный список, он содержит классы, полученные из класс, чья запись сразу предшествует списку.

inspect.getclasstree(inspect.getmro(Exception))

Или вы можете рекурсивно пройти через __subclasses__() вниз деревом наследования, например:

def classtree(cls, indent=0):
    print '.' * indent, cls.__name__
    for subcls in cls.__subclasses__():
        classtree(subcls, indent + 3)

classtree(BaseException)

печатает:

 BaseException
... Exception
...... StandardError
......... TypeError
......... ImportError
............ ZipImportError
......... EnvironmentError
............ IOError
............... ItimerError
............ OSError
......... EOFError
......... RuntimeError
............ NotImplementedError
......... NameError
............ UnboundLocalError
......... AttributeError
......... SyntaxError
............ IndentationError
............... TabError
......... LookupError
............ IndexError
............ KeyError
............ CodecRegistryError
......... ValueError
............ UnicodeError
............... UnicodeEncodeError
............... UnicodeDecodeError
............... UnicodeTranslateError
......... AssertionError
......... ArithmeticError
............ FloatingPointError
............ OverflowError
............ ZeroDivisionError
......... SystemError
............ CodecRegistryError
......... ReferenceError
......... MemoryError
......... BufferError
...... StopIteration
...... Warning
......... UserWarning
......... DeprecationWarning
......... PendingDeprecationWarning
......... SyntaxWarning
......... RuntimeWarning
......... FutureWarning
......... ImportWarning
......... UnicodeWarning
......... BytesWarning
...... _OptionError
... GeneratorExit
... SystemExit
... KeyboardInterrupt

Ответ 2

Повторно введите код из стандартной библиотеки, а не переместите свой собственный.

import inspect
import pydoc

def print_class_hierarchy(classes=()):
    td = pydoc.TextDoc()
    tree_list_of_lists = inspect.getclasstree(classes)
    print(td.formattree(tree_list_of_lists, 'NameSpaceName'))

Чтобы использовать это, нам нужна иерархия классов, в виде списка, что имеет смысл для нас передать нашу функцию. Мы можем построить это путем рекурсивного поиска результатов метода классов .__subclasses__(), используя эту функцию (которую я сохраню здесь в канонической версии):

def get_subclasses(cls):
    """returns all subclasses of argument, cls"""
    if issubclass(cls, type): # not a bound method
        subclasses = cls.__subclasses__(cls)
    else:
        subclasses = cls.__subclasses__()
    for subclass in subclasses:
        subclasses.extend(get_subclasses(subclass))
    return subclasses

Поместите это вместе:

list_of_classes = get_subclasses(int)
print_class_hierarchy(list_of_classes)

Какие принты (в Python 3):

>>> print_class_hierarchy(classes)
builtins.int(builtins.object)
    builtins.bool
    enum.IntEnum(builtins.int, enum.Enum)
        inspect._ParameterKind
        signal.Handlers
        signal.Signals
    enum.IntFlag(builtins.int, enum.Flag)
        re.RegexFlag
    sre_constants._NamedIntConstant
    subprocess.Handle
enum.Enum(builtins.object)
    enum.IntEnum(builtins.int, enum.Enum)
        inspect._ParameterKind
        signal.Handlers
        signal.Signals
enum.Flag(enum.Enum)
    enum.IntFlag(builtins.int, enum.Flag)
        re.RegexFlag

Это дает нам дерево всех подклассов, а также связанных множественных классов наследования - и сообщает нам модули, в которых они живут.