There are times when you have written your code, but while you execute, it might not run. These types of situations occur when the input is inappropriate, or you try to open a file with a wrong path or try to divide a number by zero. Due to some errors or incorrect commands, the output will not be displayed. This is because of errors and exceptions which are a part of the Python programming language. Let us learn Python Programming skills and concepts related to exception handling and allied concepts here in this blog and more about sys.argv command-line argument. Read about Self in Python as well!
What is Exception Handling?
Python raises exceptions when it encounters errors during execution. A Python exception is basically a construct that signals any important event, such as a run-time error.
Exception Handling is the process of responding to executions during computations, which often interrupts the usual flow of executing programs in advanced Python projects. It can be performed both at the software level as part of the program and also at the hardware level using built-in CPU mechanisms.
Why is Exception Handling Important?
Although exceptions might be irritating when they occur, they play an essential role in high-level languages by acting as a friend to the user.
An error at the time of execution might lead to two things: your program will die or display a blue screen of death. On the other hand, exceptions act as communication tools. It allows the program to answer the questions — of what, why, and how something goes wrong and then terminates the program in a delicate manner.
In simple words, exception handling protects against uncontrollable program failures and increases the potency and efficiency of your code. If you want to master programming, the knowledge of exceptions and how to handle them is crucial, especially in Python.
What are the Errors and Exceptions in Python?
Python doesn’t like errors and exceptions and displays its dissatisfaction by terminating the program abruptly.
There are basically two types of errors in the Python language-
- Syntax Error.
- Errors occurring at run-time or Exceptions.
1. Syntax Errors
Syntax Errors, also known as parsing errors, occur when the parser identifies an incorrect statement. In simple words, a syntax error occurs when the proper structure or syntax of the programming language is not followed.
An example of a syntax error:
>>> print( 1 / 0 ))
File "<stdin>", line 1
print( 1 / 0 ))
^
SyntaxError: invalid syntax
2. Exceptions
Exceptions occur during run-time. Python raises an exception when your code has the correct syntax but encounters a run-time issue that it cannot handle.
There are a number of defined built-in exceptions in Python which are used in specific situations. Some of the built-in exceptions are:
Exception | Cause Of Error |
---|
ArithmeticError | Raised when numerical computation fails. |
FloatingPointError | Raised when floating point calculation fails. |
AssertionError | Raised in case of failure of the Assert statement. |
ZeroDivisionError | Raised when division or modulo by zero takes place for all numerical values. |
OverflowError | Raised when the result of an arithmetic operation is very large to be represented. |
IndexError | Raised when an index is not found in a sequence. |
ImportError | Raised when the imported module is not found. |
IndentationError | Raised when indentation is not specified properly. |
KeyboardInterrupt | Raised when the user hits the interrupt key. |
RuntimeError | Raised when a generated error does not fall into any category. |
SyntaxError | Raised when there is an error in Python syntax. |
IOError | Raised when Python cannot access a file correctly on disk. |
KeyError | Raised when a key is not found in a dictionary. |
ValueError | Raised when an argument to a function is the right type but not in the right domain. |
NameError | Raised when an identifier is not found in the local or global namespace. |
TypeError | Raised when an argument to a function is not in the right type. |
There are other types of built-in exceptions called warnings. They are usually issued in situations where the user is alerted of some conditions. The condition does not raise an exception; rather it terminates the program.
What is a Python KeyError?
Before getting into KeyError, you must know the meaning of dictionary and mapping in Python.
Dictionary (dict) is an unordered collection of objects that deals with data type keys. They are Python’s implementation of data structures and are also known as associative arrays. They comprise key-value pairs, in which each pair maps the key to its associated value.
Dictionary is basically a data structure that maps one set of values into another and is the most common mapping in Python.
Exception hierarchy of KeyError:
->BaseException
->Exception
->LookupError
->KeyError
A Python KeyError is raised when you try to access an invalid key in a dictionary. In simple terms, when you see a KeyError, it denotes that the key you were looking for could not be found.
An example of KeyError:
>>> prices = { 'Pen' : 10, 'Pencil' : 5, 'Notebook' : 25}
>>> prices['Eraser']
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
prices['Eraser']
KeyError: 'Eraser'
Here, dictionary prices are declared with the prices of three items. The KeyError is raised when the item ‘Eraser’ is being accessed which is not present in prices.
Whenever an exception is raised in Python, it is done using traceback, as you can see in the example code above. It tells why an exception is raised and what caused it.
Let’s execute the same Python code from a file. This time, you will be asked to give the name of the item whose price you want to know:
# prices.py
prices = { 'Pen' : 10, 'Pencil' : 5, 'Notebook' : 25}
item = input('Get price of: ')
print(f'The price of {item} is {prices[item]}')
You will get a traceback again, but you’ll also get the information about the line from which the KeyError is raised:
Get price of: Eraser
Traceback (most recent call last):
File "prices.py", line 5, in <module>
print(f'The price of {item} is {prices[item]}')
KeyError: 'Eraser'
The traceback in the example above provides the following information:
- A KeyError was raised.
- The key ‘Eraser’ was not found.
- The line number raised the exception along with that line.
Where else will you find a Python KeyError?
Although a KeyError is often raised because of an invalid key in a Python dictionary or a dictionary subclass, you may also find it in other places in the Python Standard Library, such as in a zipfile. However, it denotes the same semantic meaning as the Python KeyError, which is not finding the requested key.
An example of such:
>>> from zipfile import ZipFile
>>> my_zip_file = ZipFile('Avengers.zip')
>>> my_zip_file.getinfo('Batman')
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
File "myzip.py", line 1119, in getinfo
'There is no item named %r in the archive' % name)
KeyError: "There is no item named 'Batman' in the archive"
In this example, the zipfile.ZipFile class is used to derive information about a ZIP archive ‘Batman’ using the getinfo() function.
Here, the traceback indicates that the problem is not in your code but in the zipfile code by showing the line which caused the problem. The exception raised here is not because of a LookUpError but rather due to the zipfile.ZipFile.getinfo()function call.
When do you need to raise a Python KeyError?
In Python Programming, it might be sensible at times to forcefully raise exceptions in your own code. You can usually raise an exception using the raise keyword and by calling the KeyError exception:
>>> raise KeyError('Batman')
Here, ‘Batman’ acts as the missing key. However, in most cases, you should provide more information about the missing key so that your next developer has a clear understanding of the problem.
Conditions to raise a Python KeyError in your code:
- It should match the generic meaning behind the exception.
- A message should be displayed about the missing key along with the missing key which needs to be accessed.
How to Handle a Python KeyError?
The main motive for handling a Python KeyError is to stop unexpected KeyError exceptions from being raised. There are a number of ways of handling a KeyError exception.
Using get()
The get()is useful in cases where the exception is raised due to a failed dictionary LookupError. It returns either the specified key value or a default value.
# prices.py
prices = { 'Pen' : 10, 'Pencil' : 5, 'Notebook' : 25}
item = input('Get price of: ')
price = prices.get(item)
if price:
print(f'The price of {item} is {prices[item]}')
else:
print(f'The price of {item} is not known')
This time, you’ll not get a KeyError because the get() uses a better and safer method to retrieve the price and if not found, the default value is displayed:
Get the price of the Eraser
The price of the Eraser is not known
In this example, the variable price will either have the price of the item in the dictionary or the default value ( which is None by default ).
In the example above, when the key ‘Eraser’ is not found in the dictionary, the get() returns None by default rather than raising a KeyError. You can also give another default value as a second argument by calling get():
price = prices.get(item,0)
If the key is not found, it will return 0 instead of None.
Checking for Keys
In some situations, the get() might not provide the correct information. If it returns None, it will mean that the key was not found or the value of the key in the Python Dictionary is actually None, which might not be true in some cases. In such situations, you need to determine the existence of a key in the dictionary.
You can use the if and in operators to handle such cases. It checks whether a key is present in the mapping or not by returning a boolean (True or False) value:
dict = dictionary()
for i in range(50):
key = i % 10
if key in dict:
dict[key] += 1
else:
dict[key] = 1
In this case, we do not check what the value of the missing key is but rather we check whether the key is in the dictionary or not. This is a special way of handling an exception that is rarely used.
This technique of handling exceptions is known as Look Before You Leap(LBYL).
Using try-except
The try-except block is one of the best possible ways to handle the KeyError exceptions. It is also useful where the get() and the if and in operators are not supported.
Let’s apply the try-except block on our earlier retrieval of the prices code:
# prices.py
prices = { 'Pen' : 10, 'Pencil' : 5, 'Notebook' : 25}
item = input('Get price of: ')
try:
print(f'The price of {item} is {prices[item]}')
except KeyError:
print(f'The price of {item} is not known')
Here, in this example, there are two cases— a normal case and a backup case. Try block corresponds to the normal case and except block to the backup case. If the normal case doesn’t print the name of the item and the price and raises a KeyError, the backup case prints a different statement or a message.
Using try-except-else
This is another way of handling exceptions. The try-except-else has three blocks— try block, except block, and else block.
The else condition in a try-except statement is useful when the try condition doesn’t raise an exception. However, it must follow all the except conditions.
Let us take our previous price retrieval code to illustrate try-except-else:
# prices.py
prices = { 'Pen' : 10, 'Pencil' : 5, 'Notebook' : 25}
item = input('Get price of:')
try:
print(f'The price of {item} is {prices[item]}')
except KeyError:
print(f'The price of {item} is not known')
else:
print(f'There is no error in the statement')
First, we access an existing key in the try-except block. If the Keyerror is not raised, there are no errors. Then the else condition is executed and the statement is displayed on the screen.
Using finally
The try statement in Python can have an optional final condition. It is used to define clean-up actions and is always executed irrespective of anything. It is generally used to release external sources.
An example to show finally:
# prices.py
prices = { 'Pen' : 10, 'Pencil' : 5, 'Notebook' : 25}
item = input('Get price of: ')
try:
print(f'The price of {item} is {prices[item]}')
except KeyError:
print(f'The price of {item} is not known')
finally:
print(f'The finally statement is executed')
Remember, the final statement will always be executed whether an exception has occurred or not.
Top Cities Where Knowledgehut Conduct Python Certification Course Online
How to raise Custom Exceptions in Python?
Python comprises a number of built-in exceptions which you can use in your program. However, when you’re developing your own packages, you might need to create your own custom exceptions to increase the flexibility of your program.
You can create a custom Python exception using the pre-defined class Exception:
def square(x):
if x<=0 or y<=0:
raise Exception('x should be positive')
return x * x
Here, the function square calculates the square of a number. We raise an Exception if either the input number is negative or not.
Disadvantages of Exception Handling
Though exception handling is very useful in catching and handling exceptions in Python, it also has several disadvantages. Some of these are as follows—
- It can trap only run-time errors.
- When you use try-except, the program will lose some performance and slow down a bit.
- The size of the code increases when you use multiple try, except, else, and finally blocks.
- The concept of try-catch might be a little difficult to understand for beginners.
- It is useful only in exceptional error cases.
Other than these disadvantages, understanding the concept of Exception Handling can ease your career as a programmer in the world of Python.
Conclusion
Since you have now become quite an expert in handling KeyError exceptions, you can easily debug actual errors and reduce the number of bugs in your code.
Let us sum up what we’ve learned in the article so far:
- Exception Handling and its importance.
- Different types of exceptions.
- Python KeyError
- Finding and raising a Python KeyError.
- Handling Python KeyError.
- Custom Exceptions.
- Demerits of Exception Handling.
Exceptions are considered the tools of communication that guard you against potential damage. If you’re clear in the understanding of exceptions, they will act as a guide to your solutions.
So next time you see a Python KeyError raised, you’ll find all the information about the location of your error and how to handle that. You will easily know how to access the key using the safer get() or, the more general try-except-else blocks to control your program’s flow more efficiently and predictably.
However, suppose you wish to know more about errors and exceptions. You can look into the full documentation of Python Standard Library’s errors and exceptions and exception handling or enroll in KnowledgeHut learn Python Programming courses. You can also learn more about Python Programming in this complete Python Tutorial.