User-defined exception classes

In Python, you can create your own exception classes. They must directly or indirectly be descendants of the Exception class.

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!

In this case, an instance of own exception class is created in the expression MyError("You give negative!"). Using raise the exception is raised. In the corresponding except branch that intercepts it, the exception is assigned to the variable mr.

The objects of the Exception class (and children of it) have the __str__() method defined to display the attribute values. Therefore, you can not refer directly to the fields of the object, for example, like this: mr.txt.

In addition, Exception instances have an args attribute. Through it, you can access individual fields:

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

The example of inheritance from exception classes. When intercepted, the parent class "catches" the children, but not vice versa.

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'>