Создание классов исключений

В Python можно создавать собственные классы исключений. Они должны напрямую или опосредованно быть потомками класса Exception.

class MyError(Exception):
    def __init__(self, text):
        self.txt = text


a = input("Input positive integer: ")

try:
    a = int(a)
    if a < 0:
        raise MyError("You give negative!")
except ValueError:
    print("Error type of value!")
except MyError as mr:
    print(mr)
else:
    print(a)

Пример выполнения:

Input positive integer: -10
You give negative!

В данном случае в выражении MyError("You give negative!") создается экземпляр собственного класса исключений. С помощью raise исключение возбуждается. В перехватившей его соответствующей ветке except исключение присваивается переменной mr.

У объектов класса Exception (и производных от него) определен метод __str__() так, чтобы выводить значения атрибутов. Поэтому можно не обращаться напрямую к полям объекта, например, так: mr.txt.

Кроме того у экземпляров Exception есть атрибут args. Через него можно получать доступ к отдельным полям:

class MyError(Exception):
    def __init__(self, text, num):
        self.txt = text
        self.n = num


a = input("Input positive integer: ")

try:
    a = int(a)
    if a < 0:
        raise MyError("You give negative!", a)
except ValueError:
    print("Error type of value!")
except MyError as mr:
    print(mr)
    print(mr.args)
    print(mr.args[0])
    print(mr.args[1])
else:
    print(a)

Пример выполнения:

Input positive integer: -3
('You give negative!', -3)
('You give negative!', -3)
You give negative!
-3

Пример наследования от классов-исключений. При перехвате родительский класс "ловит" дочерние, но не наоборот.

class General(Exception): pass
class Specific1(General): pass
class Specific2(General): pass

def raiser0():
    x = General()
    raise x

def raiser1():
    x = Specific1()
    raise x

def raiser2():
    x = Specific2()
    raise x

for func in (raiser0, raiser1, raiser2):
    try:
        func()
    except General:
        import sys
        print(sys.exc_info()[0])
<class '__main__.General'>
<class '__main__.Specific1'>
<class '__main__.Specific2'>