Python Exception Handling – Learn errors and exceptions in Python

In this Python exception handling article, we will talk about errors and exceptions in Python. We will also see how to raise and catch them. We will also learn about different keywords used for exception handling in Python.

What are Exceptions in Python Exception Handling?

Python is an interpreted language. When you are coding in the Python interpreter, you often have to deal with runtime errors. These are runtime exceptions.

When there is an exception, all execution stops and it displays a red error message on the screen. But if we can handle it, the program will not crash. So an exception is when something goes wrong and your program cannot run anymore.

Python has built-in exceptions but you can also define your own exceptions. This code raises an exception:

Code:

>>> print(1/0)

Output:

Traceback (most recent call last):
  File “<pyshell#213>”, line 1, in <module>
    print(1/0)
ZeroDivisionError: division by zero

It is not possible to divide 1 by 0, so the program has to stop, it cannot execute anymore. So it raises a ZeroDivisionError. This is an in-built exception in Python.

All exceptions inherit from the Exception base class.

The try-except Blocks in Python Exception Handling

If you know an operation can raise an exception, you can put it in a try-block. Like the if-statement, indentation is mandatory for the try-block.

Code:

>>> nums=[1,2,3]
>>> nums[3]

Output:

Traceback (most recent call last):
  File “<pyshell#216>”, line 1, in <module>
    nums[3]
IndexError: list index out of range

Here, the list nums only has 3 items. So they must have indices 0 to 2.

If we try to access the item at index 3, it will raise an IndexError and the program will stop. But if we catch this exception in the except block, the program will continue running from the next statement.

Code:

>>> try:
  nums[3]
except:
  print('Out of index!')

Output:

Out of index!

Now whatever is after these 4 lines will be executed normally. In the except block, we can put anything – assignment, function calls, or anything else. We can also get the exception that occurred by importing sys.

Code:

>>> import sys
>>> try:
  nums[3]
except:
  print('Out of index!')
  print(sys.exc_info())

Output:

Out of index!
(<class ‘IndexError’>, IndexError(‘list index out of range’), <traceback object at 0x00000289E33498C8>)

Catching Specific Exceptions in Python Exception Handling

This catches any exception in the same way.

If you know which exception will be raised by a piece of code, you can specifically catch that exception by mentioning it with except. We can have any number of except clauses after a try clause, but only one generic except clause in the end.

Code:

>>> try:
  pass
except ZeroDivisionError
SyntaxError: invalid syntax
>>> try:
  pass
except ZeroDivisionError:
  pass
except (IndexError, NameError):
  pass
except:
  pass

If you want to specify more than one exception in an except clause, you need to write it in a tuple.

The Finally Clause in Python Exception Handling

Sometimes even if an exception is raised, you may want to do something – like close a file.

You can put a finally clause after the last except and then put the code in this – the code you want to execute no matter what.

Code:

>>> try:
  f=open('text.txt')
  f.write('Hello')
except:
  pass
finally:
  f.close()

In this code, it opens a file text.txt, tries to write ‘Hello’ to the file.

It raises an exception because we opened the file in read-mode and are trying to write to it. But we don’t handle this exception. Finally, we want to close this file. The code in the finally-block does this.

Raising Exceptions in Python

Python raises an exception when there is a problem, but we can also forcefully raise an exception. We do this with the raise keyword. Unlike this, Java has the throw keyword for this.

Code:

>>> raise OSError

Output:

Traceback (most recent call last):
  File “<pyshell#246>”, line 1, in <module>
    raise OSError
OSError

This code raises an OSError.

This was in the interpreter but we can put this anywhere in our code.

  • We can also raise a RuntimeError.

Code:

>>> raise

Output:

Traceback (most recent call last):
  File “<pyshell#247>”, line 1, in <module>
    raise
RuntimeError: No active exception to reraise
  • You can tell it which exception to raise along with a description of it.

Code:

>>> raise OSError('There was an OS Error')

Output:

Traceback (most recent call last):
  File “<pyshell#248>”, line 1, in <module>
    raise OSError(‘There was an OS Error’)
OSError: There was an OS Error

This gives us a bit of description about the exception that occurred.

else with try-except

You can follow a try-except block with an else-block. If no exception is raised in the try-block, the code in the else-block executes.

Code:

>>> try:
  print(1)
except:
  print(2)
else:
  print(3)

Output:

1
3

Standard Exceptions in Python Exception Handling

Before learning to create our own exceptions, let’s see some in-built exceptions in Python.

  • Exception – Base class for all exceptions
  • StopIteration – When an iterator ends
  • SystemExit – Raised by sys.exit()
  • StandardError – Base class for in-built exceptions except StopIteration and SystemExit
  • ArithmeticError – Base class for arithmetic calculation errors
  • OverFlowError – When a calculation exceeds the maximum limit
  • FloatingPointError – When a floating-point operation fails
  • ZeroDivisionError – When there is division or modulus by 0
  • AssertionError – When an assert statement fails
  • AttributeError – When an attribute reference or assignment fails
  • EOFError – On reaching the end of the file with no input from input()
  • ImportError – When an import statement fails
  • KeyboardInterrupt – When you interrupt execution by pressing Ctrl+C
  • LookupError – Base class for lookup errors
  • IndexError – When an index is not in a sequence
  • KeyError – When a key is not present in a dictionary
  • NameError – When an identifier is not present in the local/global namespace
  • UnboundLocalError – When we access a local variable which hasn’t been assigned yet
  • EnvironmentError – Base class for exceptions outside the Python environment
  • IOError – When an input/output operation fails
  • OSError – For operating system-related errors
  • SyntaxError – When the syntax is incorrect
  • IndentationError – When there is not proper indentation
  • SystemError – When the interpreter has an internal problem
  • SystemExit – When the interpreter quits because of sys.exit()
  • TypeError – When an operation is invalid for specific data type
  • ValueError – When the in-built function has a valid type of arguments but invalid values
  • RuntimeError – When an error doesn’t fall in any other category
  • NotImplementedError – When an abstract method is not implemented in an inherited class

Defining our own exceptions in Python Exception Handling

Until now, we talked about in-built exceptions in Python. Now, let’s learn to define our own exceptions.

For this, you should:

1. Create a class

2. Make it inherit from Exception or another exception class

Code:

>>> class InvalidTemperature(Exception):
  def __init__(self, temp):
    self.temp=temp
  def __str__(self):
    return f'The temperature {self.temp} is low'

Code:

>>> raise InvalidTemperature(30)

Output:

Traceback (most recent call last):
  File “<pyshell#283>”, line 1, in <module>
    raise InvalidTemperature(30)
InvalidTemperature: The temperature 30 is low

We can catch this exception by using try-except blocks.

Code:

>>> try:
  raise InvalidTemperature(30)
except:
  print('Ok')

Output:

Ok

AssertionError in Python

Let’s also talk about AssertionError.

But first, let’s talk about assert statements. The assert statement takes a condition that has to be true. If it isn’t, it raises an AssertionError and the program stops executing.

So if the condition is True, the program continues running. But if it’s not, it stops and raises an AssertionError exception. This is an in-built exception.

Code:

>>> marks=-4
>>> assert (marks>=0 and marks<=100)

Output:

Traceback (most recent call last):
  File “<pyshell#308>”, line 1, in <module>
    assert (marks>=0 and marks<=100)
AssertionError

If marks are -4 and we have an assert statement that says it should be in 0 to 100, it raises an AssertionError.

We can also give it a description for the error.

Code:

>>> assert (marks>=0 and marks<=100), 'Marks should be >=0 and <=100'

Output:

Traceback (most recent call last):
  File “<pyshell#309>”, line 1, in <module>
    assert (marks>=0 and marks<=100), ‘Marks should be >=0 and <=100’
AssertionError: Marks should be >=0 and <=100

Summary

So today we talked about Python exception handling.

We saw try-except blocks, catching specific exceptions, the finally clause, raising exceptions, standard exceptions, custom exceptions, and AssertionError in Python exception handling.

This was all about TechVidvan’s Python exception handling article.