An exception is an event that occurs during the execution of a program that disrupts its normal flow, often due to an error or an unusual condition. It allows the program to handle errors gracefully instead of crashing. When an error happens, Python “raises an exception”, which means:
“I can’t keep going — something’s wrong!”
If you don’t handle it, your program stops and shows an error message. Here's a simple error you can look at:
>>> print(10 / 0)
Traceback (most recent call list):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
And in this example:
ZeroDivisionError is the exception type (a class).
division by zero is the error message.
You can “catch” and “handle” exceptions using try and except.
try:
print(10 / 0)
except ZeroDivisionError:
print("You can’t divide by zero, you loon!")
Output:
You can’t divide by zero, you loon!
Now your program continues safely instead of stopping.
We can catch different types of Exceptions
try:
number = int("hello")
except ValueError:
print("That’s not a number!")
Output:
That’s not a number!
Note that if we did not print this message, the default result would be a raised exception:
ValueError: invalid literal for int() with base 10: 'hello'
Other errors are less obvious, for example:
a = 10000
if a > 2999
print("Eligible")
will raise another type of error:
if a > 2999
^
SyntaxError: expected ':'
and you can see that it is "pointing" to where the missing colon is. Say we fix this and run the following:
a = 10000
if a > 2999:
print("Eligible")
Now we will get a different error message:
IndentationError: expected an indented block after 'if' statement on line 2
In Python, indentation is critical as it has meaning- indentation communicates what is inside a loop, conditional block or function and what is not in these structures.
It is the same problem if we create a function with no body:
def foo():
print("Done")
We get:
IndentationError: expected an indented block after function definition on line 1
We can fix this by using the pass command. The pass statement in Python is a placeholder that does nothing when executed.
It is used to keep code blocks valid where a statement is required but no logic is needed yet.
Examples situations where pass is used are empty functions, classes, loops or conditional blocks.
This means we can plan to create many functions, loop, conditional checks etc. and then we can code them one-by-one. Using pass means we will not get an error for an empty (as yet to be created) function, as in this example:
def foo():
pass
print("Done")
Another common error is a result of humans not paying attention:
a = 10
b = a + c # cannot reference a variable before it is created
c = 3.2
Resulting in:
Traceback (most recent call last):
File "<string>", line 2, in <module>
NameError: name 'c' is not defined
Note that the error occurs at the point where that line is interpreted, and crashes out immediately.
The hierarchy of Exceptions in Python
Some common built-in exceptions other than above mentioned exceptions are:
IndexError: When the wrong index of a list is retrieved.
AssertionError: It occurs when the assert statement fails
AttributeError: It occurs when an attribute assignment is failed.
ImportError: It occurs when an imported module is not found.
KeyError: It occurs when the key of the dictionary is not found.
NameError: It occurs when the variable is not defined.
MemoryError: It occurs when a program runs out of memory.
TypeError: It occurs when a function and operation are applied in an incorrect type.
An exception in Python is a class- just as variables are classes (str, int, list etc.) and functions are also objects- so too are exceptions. There are many types of exceptions that can happen, but they all inherit from the BaseException class. These classes are sub-classes of BaseException, and you instantiate them (optionally with arguments) to signal an error condition. Then the interpreter raises that instance.
We can create our own type of Exception class if we wish, e.g.
class MyError(Exception):
pass
and we could raise it like:
raise MyError("Something went wrong")
All built-in exceptions (like ValueError, TypeError, IOError, etc.) are classes — and you can verify this:
>>> isinstance(ValueError, type)
True