Python Exception

When a python program leads to an uncepected error, it will terminate. Such event is called an exception. An exception refers to the event the disrupt the normal flow of the python program.

Tow useful tutorials:

Exception can be either user-defined or built-in. For built-in exception, we refer to official document exceptions. The built-in exceptions are defined under the base class Exception. Note that BaseException is the base class of Exception. As we will mention later, the exception handling only applies to Exception class.

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      |    +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

Exception Handling

Exception handling refers to catching the exception and then do corresponding operations. The following keywords are related to exception handling: try, except, finally, with.

try... except...else... block

The basic way to do exception is to use try... except... else... block. The following is the syntax.

try:
   # You do your operations here;
   # ......................
except ExceptionI:
   # If there is ExceptionI, then execute this block.
except ExceptionII:
   # If there is ExceptionII, then execute this block.
   # ......................
else:
   # If there is no exception then execute this block. 

There are also many variants of the block.

(1) The else is not necessary.

try:
    a = 1 / 0
except:
    print("an exception occurs.")

(2) Catching specific exceptions

try:
    # do some thing 
except ValueError:
    # handle ValueError exception
    # do somthing
    pass
except (TypeError, ZeroDivisionError):
    # handle multiple exceptions
   	# TypeError and ZeroDivisionError
    pass
except: 
    # handle all other exceptions
    pass

For each specific exception type, we can refer to the built-in exception list mentioned at the beginning.

The advantage of this variant is that we can only hadle specific types of exceptions instead of all of them, which can save time.

(3) Evaluate exception type

try:
    # do something
except Exception as e:
    print("Oops!", e.__class__, "occurred.")

If we do not know what type of exception will occur, we can assign the exception to a variable and access its class to read the exception type.

try...finally block

The finally block is a place to put any code that must execute, whether the try block raised an exception or not. Syntax is as follows:

try:
   #You do your operations here;
   # ......................
   #Due to any exception, this may be skipped.
finally:
   # This would always be executed.
   #......................

It can be nested to try...except block. For example,

try:
   fh = open("testfile", "w")
   try:
      fh.write("This is my test file for exception handling!!")
   finally:
      print "Going to close the file"
      fh.close()
except IOError:
   print "Error: can\'t find file or read data"

with block

The with statement clarifies code that previously would use try...finally blocks to ensure that clean-up code is executed. It can be viewed as a simplification of try...finally block. The basic structure is:

with expression [as variable]:
    # do something equivalent to the finally block

It is usually used in the file operation, for example,

with open('output.txt', 'w') as f:
     f.write('Hi there!')

Raising an Exception

The keyword raise is used to raise an exception. The syntax goes as follows:

x = "hello"
if not type(x) is int:
  raise TypeError("Only integers are allowed")

User-defined Exception