Exception handling in Python

Posted by anhedonia on Sun, 20 Feb 2022 10:33:26 +0100

The art and Tao of Python Programming: an introduction to Python language
Link to the video course "the art and Tao of Python Programming: an introduction to Python language": https://edu.csdn.net/course/detail/27845

exception handling

Errors detected during execution are called exceptions. Exceptions are events that can modify the control flow through the program.

Exceptions don't have to have serious consequences: you'll learn how to handle them in Python programs. However, most exceptions are not handled by the program, and an error message is displayed.

Exception handling: in Python, exceptions are automatically triggered in case of errors, and can be triggered and intercepted by code.

10 * (1/0)
---------------------------------------------------------------------------

ZeroDivisionError                         Traceback (most recent call last)

<ipython-input-1-0b280f36835c> in <module>
----> 1 10 * (1/0)


ZeroDivisionError: division by zero
4 + spam*3
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-2-c98bb92cdcac> in <module>
----> 1 4 + spam*3


NameError: name 'spam' is not defined
 '2' + 2
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-3-d2b23a1db757> in <module>
----> 1 '2' + 2


TypeError: can only concatenate str (not "int") to str

We will learn three exception handling statements. The first statement has two variants (listed separately here):

  • try/except:

    • Catch and recover from exceptions raised by Python, or by you
  • try/finally:

    • Perform cleanup actions, whether exceptions occur or not.
  • raise:

    • Trigger an exception manually in your code.
  • assert:

    • Conditionally trigger an exception in your code.

try/except statement

try:
    statements           # Run this main action first
except name1:       
  # Run if name1 is raised during try block
    statements
except (name2, name3):   
   # Run if any of these exceptions occur
    statements 
except name4 as var:     
     # Run if name4 is raised, assign instance raised to var 
    statements
except:                  # Run for all other exceptions raised
    statements
else:
    statements           # Run if no exception was raised during try block

A try statement may have multiple except clauses to specify different exception handlers.

while True:
    try:
        x = int(input("Please enter a number: "))
        break
    except ValueError:
        print("Oops!  That was no valid number.  Try again...")
Please enter a number: q
Oops!  That was no valid number.  Try again...
Please enter a number: w
Oops!  That was no valid number.  Try again...
Please enter a number: 7

An exception clause can name multiple exceptions as parenthesized tuples, for example:

  except (RuntimeError, TypeError, NameError):
      pass

try/finally statement

try:
    raise KeyboardInterrupt
finally:
    print('Goodbye, world!')
Goodbye, world!



---------------------------------------------------------------------------

KeyboardInterrupt                         Traceback (most recent call last)

<ipython-input-5-ca8991ac7661> in <module>
      1 try:
----> 2     raise KeyboardInterrupt
      3 finally:
      4     print('Goodbye, world!')


KeyboardInterrupt: 

In the case of multiple except clauses, the last exception clause can omit the exception name to be used as a wildcard. But please use it with caution, because it's easy to cover up real programming errors in this way! It can also be used to print error messages and then re throw exceptions (also allowing the caller to handle exceptions):

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise
OS error: [Errno 2] No such file or directory: 'myfile.txt'

The try... Except statement has an optional else clause, which must be placed after all except clauses when used. It is useful for code that must be executed when the try clause does not throw an exception.

For example:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()
cannot open -f
C:\Users\Bai\AppData\Roaming\jupyter\runtime\kernel-481b4f2c-b727-4b32-bb28-317208866d1c.json has 12 lines

Throw exception

raise statement allows the programmer to force a specified exception to be thrown. For example:

raise NameError('HiThere')
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-8-72c183edb298> in <module>
----> 1 raise NameError('HiThere')


NameError: HiThere

try/finally statement

try:
    raise KeyboardInterrupt
finally:
    print('Goodbye, world!')
Goodbye, world!



---------------------------------------------------------------------------

KeyboardInterrupt                         Traceback (most recent call last)

<ipython-input-9-ca8991ac7661> in <module>
      1 try:
----> 2     raise KeyboardInterrupt
      3 finally:
      4     print('Goodbye, world!')


KeyboardInterrupt: 

User defined exception

Programs can name their own exceptions by creating new Exception classes. Exceptions should usually derive directly or indirectly from the Exception class.

class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class InputError(Error):
    """Exception raised for errors in the input.

    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """

    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """

    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message

Topics: Python Back-end