BlogsDope image BlogsDope

Exception Handling in Python

Dec. 15, 2020 PYTHON EXCEPTION 1397

In Python, errors are generally of two types: syntax errors and exceptions. When a syntax error occurs, the program fails to execute, and the parser shows where the error occurred. Consider the following example.

print("This statement causes a syntax error)

Output

Exceptions, on the other hand, are the errors that occur when a syntactically correct code runs into a problem during its execution. If an exception is not handled, then the program crashes. The error message is shown consisting of the exception type, details, and the context where it happened.

print("my name is " + name)
Name error in Python

The try and except block


However, we can write programs that handle exceptions. We can do it by using try and except statements. The try block contains the code that can throw an exception. The except clause handles the exception that occurs in the try clause.

An except statement optionally takes an exception type, which follows the except keyword. If an exception type is provided, then that block gets executed only if the raised exception matches the specified type. If no exception type is provided, then that except clause gets executed for any type. This, however, is not recommended, as it does not give information about the raised exception.

Consider the following example, where we divide two numbers. Now, there is a possibility that a number can be divided by zero, and hence, ZeroDivisionError exception can occur. Therefore, we put the suspicious code in the try block. We also add an except block to handle that exception.

a = 12
b = 12
try:
    result = a / b
    print(f"The result of the division is: {result}")
except ZeroDivisionError:
    print("Division by zero is undefined")

print("End Program")

Output

​The result of the division is: 1.0
End Program

Here, the variable b has a non-zero value. Therefore, no exception gets raised. The try clause executes without any interruption, and no except clause runs.

a = 12
b = 0
try:
    result = a / b
    print(f"The result of the division is: {result}")
except ZeroDivisionError:
    print("Division by zero is undefined")

print("End Program")

Output

Division by zero is undefined
End Program

Now, the variable b has a zero value. So, the ZeroDivisionError exception occurs at line 4, and no lines in the try clause get executed after that. Since an except clause exists that handles the ZeroDivisionError exception, it gets executed. After this, statements after the try and except blocks run. If an exception is not handled either by any current or outer except clause, then the program’s execution is interrupted, and the error message gets displayed.

Multiple except clauses


A try statement can have multiple except statements. However, only one executes at one time. Let’s take an example.

a = 12
b = "2"
try:
    result = a / b
    print(f"The result of the division is: {result}")
except ZeroDivisionError:
    print("Division by zero is undefined")
except NameError:
    print("Please define all the variable")
except TypeError:
    print(
        "Please make sure that the variable types are supported for division operation"
    )
except:
    print("Unexpected error")

print("End Program")

Output

​Please make sure that the variable types are supported for division operation
End Program

The above code contains different except statements to handle various exceptions. Since we are attempting to divide a number by a string value, we get a TypeError exception, which gets handled in the corresponding except clause. Here, we also have a generic except block that does not contain any exception type and handles exceptions other than the specified ones. Remember that you must put the default except statement after all the other except statements. Otherwise, you will get a syntax error.

An except clause with multiple exception types


You can also have an except clause that handles multiple exceptions. This is useful when you want to run the same type of statements for different exception types.

a = 12
b = "2"
try:
    result = a / b
    print(f"The result of the division is: {result}")
except (ZeroDivisionError, NameError, TypeError):
    print("Error Message: Make sure that both operands are valid")

print("End Program")

Output

​Error Message: Make sure that both operands are valid
End Program

The else clause


The else clause comes after all the except statements. It only runs when no exception occurs in the try block.

a = 12
b = "2"
try:
    result = a / b
    print(f"The result of the division is: {result}")
except ZeroDivisionError:
    print("Division by zero is undefined")
except NameError:
    print("Please define all the variable")
except TypeError:
    print(
        "Please make sure that the variable types are supported for division operation"
    )
except:
    print("Unexpected error")
else:
    print("division performed successfully")

print("End Program")

Output

​Please make sure that the variable types are supported for division operation
End Program

As you can see above, the else clause does not run when an exception gets raised.

a = 12
b=2
try:
  result = a/b
  print(f"The result of the division is: {result}")
except ZeroDivisionError:
  print("Division by zero is undefined")
except NameError:
  print("Please define all the variable")
except TypeError:
  print("Please make sure that the variable types are supported for division operation")
except:
  print("Unexpected error")
else:
  print("division performed successfully")

print("End Program")

Output

​The result of the division is: 6.0
division performed successfully
End Program

Since the try block runs without any interruption, the else clause gets executed.

The exception’s argument


The exception’s argument is a value that gives us information about the exception. To get that additional info, add a variable after the exception type in the except statement. The contents and the presence of the argument depend upon the type of exception. Let’s see.

Consider the example in which we try to read a file that does not exist.

try:
    f = open("sample.txt", "r")
    print(f.read())
except FileNotFoundError as arg:
    print(type(arg))
    print(arg)
else:
    print("File read successfully")

Output

​<class 'FileNotFoundError'>
[Errno 2] No such file or directory: 'sample.txt'

The finally clause


While the else clause executes when the try clause does not raise any exception, the finally clause runs whether or not an exception occurs in the try block. Therefore, it is used to define clean-up actions such as closing files, releasing resources, etc.

Consider the following example.

try:
    f = open("sample.txt", "r")
    print(f.read())
except FileNotFoundError as arg:
    print(arg)
else:
    print("File read successfully")
finally:
    print("finally clause")

Output

[Errno 2] No such file or directory: 'sample.txt'
finally clause

In the above example, we again try to read a file that does not exist. Therefore, the FileNotFoundError exception gets raised. Since we handle that type, the corresponding clause runs. After that, the finally clause runs. If we don't handle it, the exception will be re-thrown after the finally clause finishes its execution.

try:
  f = open("sample.txt", "r")
  print(f.read())
except TypeError as arg:
  print(arg)
else:
  print("File read successfully")
finally:
   print("finally clause")

Output

Python File not found exception

Let’s see the output when no exception occurs, i.e., we create a new sample.txt file.

try:
    f = open("sample.txt", "r")
    print("Contents of the file are:")
    print(f.read())
except FileNotFoundError as arg:
    print(arg)
else:
    print("File read successfully")
finally:
    print("finally clause")

Output

​Contents of the file are:
This is a sample file.
File read successfully
finally clause

Note that, if the try block (or any other) contains a return statement or a break statement, the finally clause still runs.

Throw an exception


You can throw an exception by yourself using the raise keyword, which is followed by the exception that you want to throw.

distance = -4
try:
    if distance < 0:
        raise ValueError  # or ValueError()
    else:
        print("the distance covered is {distance} km")
except ValueError:
    print("Distance can't be negative")

Output

​Distance can't be negative

If you want to pass additional information, then:

distance = -4
try:
    if distance < 0:
        raise ValueError("Distance can't be negative")
    else:
        print("the distance covered is {distance} km")
except ValueError as arg:
    print(arg)

Output

​Distance can't be negative

User-defined Exceptions


You can also create custom exceptions in Python. The custom exception class should be derived from the Exception class, directly or indirectly.

Let’s create a class that raises an exception when the score of the student is not between 0 and 100. Let’s see.

class OutOfRange(Exception):
  def __init__(self, msg="Score is not in the valid range, i.e., 0-100"):
    self.msg = msg
    super().__init__(self.msg)

score = 400
try: 
  if not (score >= 0 and score <=100):
    raise OutOfRange
  print(f"the score of the student is {score}")
except OutOfRange as arg:
  print(arg)

Output

​Score is not in the valid range, i.e., 0-100


Liked the post?
A computer science student having interest in web development. Well versed in Object Oriented Concepts, and its implementation in various projects. Strong grasp of various data structures and algorithms. Excellent problem solving skills.
Editor's Picks
0 COMMENT

Please login to view or add comment(s).