Exception Handling In Python

In Python language, we got two kinds of errors, the first is Syntax errors, and another is Exceptions. Syntax errors are raised due to some syntactical mistakes. They can be removed by modifying the code, whereas Exceptions can be defined as unusual events that interrupt the program's normal flow of execution.

What are Python Exceptions?

Python Exceptions are unexpected conditions that can lead to program termination or unpredictable results. Exceptions occur in Python because of internal failure of some conditions, not because of wrong syntax or semantics. Sometimes, exceptions halt the execution of code, and sometimes not, but it changes the flow of execution of the code.

Python has many in-built error handling techniques. Python Exceptions are situations that prevent the normal flow of execution of the program. Some rare cases cause the program to crash if not appropriately handled. All the exceptions are derived from the Exception class in Python. Some built-in exceptions in Python are:

  • AssertionError
  • EOFError
  • FloatingPointError
  • KeyError
  • IndexError
  • KeyboardInterrupt
  • NameError
  • RuntimeError
  • TypeError
  • ZeroDivisionError
  • ValueError
  • MemoryError

Exception Handling in Python

Python uses the following methods for exception handling:

  1. Try and Except statement
  2. Except Statement
  3. Raising Exception
  4. Using else with a try statement
  5. Using else with a try statement

Python Try and Except statement.

Python handles exceptions with try…except statements. The suspicious part of the code that can raise an exception is written inside the try block, whereas the except block is used to write code that can handle the exception. Like this

			

def reverse(num):
inverse = 0
try:
	inverse = 1/num
	print(inverse)
except:
	print("Undefined Inverse")

reverse(0)

				

Output:

Undefined Inverse

We can catch an exception and get its class using the __class__ attribute. Like this

			

def reverse(num):
	inverse = 0
	try:
		inverse = 1/num
		print(inverse)
	except Exception as e :
		print(e.__class__)
	reverse(0)

				

Output:

<class 'ZeroDivisionError'></class>

Python Except Statement

We can also catch only specific exceptions using the except statement. Multiple exceptions in the form of exceptions can be handled by specifying the exceptions in the form of a tuple. Like this

			

Def c reverse(num):
	inverse = 0
	try:
		inverse = 1/num
		print(inverse)
	except ZeroDivisionError :
		print("Exception Occured")
	reverse(0)

				

Output:

Exception occured
			

def reverse (numbers : list):
	inverse = []
	try:
		for num in numbers:
			inverse.append(1/num)
		return inverse
			
	except (ZeroDivisionError, IndexError) as e:
		print("This Exception Occured : ",e.__class__)
	
	change([1,2,6,8,0,99,12,5])

				

Output:

This Exception Occured : <class 'ZeroDivisionError'>

Python Raising Exceptions

Programmers can raise an exception by using the raise keyword. The exception type can also be specified after the raise keyword. Like this

			

def reverse (numbers : list):
	inverse = []
	try:
		for num in numbers:
			if num==0:
				raise ZeroDivisionError()       #raising exceptions explicitly
			inverse.append(1/num)
		return inverse
			
	except (ZeroDivisionError, IndexError) as e:
		print("This Exception Occured : ", e.__class__)
	
	reverse ([1,2,6,8,0,99,12,5])

				

Output:

This Exception Occured : <class 'ZeroDivisionError'>

Python - Using else with try statement

Else block can be affiliated with the try block. The else block is executed if the piece of code in the try block executes without raising any exceptions or errors. One thing to note is that if the code in the else block raises an exception, it cannot be handled by the previous except block.

			

def reverse (numbers : list):
	inverse = []
	try:
		for num in numbers:
			inverse.append(1/num)
	except (ZeroDivisionError, IndexError) as e:
		print("This Exception Occured : ", e.__class__)
	else:
		print("Else Block Executed")

	return inverse
	reverse ([1,2,6,8,99,12,5])

				

Output:

Else Block Executed

If we try raising an exception in the else block, like this

			

def reverse (numbers : list):
	inverse = []
	try:
		for num in numbers:
			inverse.append(1/num)
	except (ZeroDivisionError, IndexError) as e:
		print("This Exception Occured : ", e.__class__)
	else:
		raise IndexError
	return inverse
	reverse ([1,2,6,8,99,12,5])

				

Output:

IndexError

In the above code snippet, the IndexError exception that we tried raising in the else block is not handled by the except block above it.

Python - Using finally statement

If we want some piece of code to get executed, no matter whether an exception is raised in the try block or not, we use the finally block. This block is always executed. This is mostly used to free up resources after the program is no longer using them. Like this

			

try:
	python_file = open("python.txt", 'r')   
	print(python_file.readline())
	print(python_file.readline())
	print(python_file.readline())
finally:
	python_file.close()

				

Generally, file-related codes are performed in try…finally blocks. This is done because if the code raises an error before properly closing the file, the data inside the file can be corrupted. Code that handles File I/O should be written in the try block while the code related to closing the file object is put inside the finally block.