10+ simple examples to learn python try except in detail

In this tutorial we will learn all about handling errors and exceptions in Python programming using try..except block.

 

Python built-in exceptions

Before we start with try..except block, let us go through some of the in-built exceptions from Python. Python ships with a ton of built-in exception classes to cover a lot of error situations so that you do not have to define your own. These classes are divided into Base error classes, from which other error classes are defined, and Concrete error classes, which define the exceptions you are more likely to see from time to time.

Following are some of the common error and exception classes:

  • SyntaxError: It occurs when you type a line of code which the Python interpreter is unable to parse
  • ImportError: It occurs when an import cannot be resolved.
  • KeyError: It occurs when a dictionary key is not found while trying to access it
  • TypeError: It occurs if you attempt to do an operation on a value or object of the wrong type
  • AttributeError: It is raised when assigning or referencing an attribute fails.
  • IndexError: It occurs if you are trying to access an index (for example, in a list) which does not exist.
  • NameError: It occurs when a specified name cannot be found either locally or globally
  • FileNotFoundError: This error is raised if a file you are attempting to read or write is not found

 

Handling Errors and Exceptions

Python uses special objects called exceptions to manage errors that arise during a program’s execution. Whenever an error occurs that makes Python unsure what to do next, it creates an exception object. If you write code that handles the exception, the program will continue running. If you don’t handle the exception, the program will halt and show a traceback, which includes a report of the exception that was raised.

 

Different try statement clauses

When you write a try statement, a variety of clauses can appear after the try header. Below summarizes all the possible forms which we will cover in this tutorial.

Clause FormInterpretation
except:Catch all (or all other) exception types.
except name:Catch a specific exception only.
except name as value:Catch the listed exception and assign its instance.
except (name1, name2):except (name1, name2):
except (name1, name2) as value:Catch any listed exception and assign its instance.
else:Run if no exceptions are raised in the try block.
finally:Always perform this block on exit.

 

try..except block

Exceptions are handled with try-except blocks. A try-except block asks Python to do something, but it also tells Python what to do if an exception is raised. When you use try-except blocks, your programs will continue running even if things start to go wrong. Instead of tracebacks, which can be confusing for users to read, users will see friendly error messages that you write.

Syntax

The basic syntax to use try..except blocks would be:

try:
  # do something here
except [Exception]:
  # If there is Exception, then execute this block.

You can define multiple exception blocks to handle different kind of exceptions. We will cover this using different examples to help you understand better.

 

Example-1: Handling single exception

Before I handle exceptions, let me show you a general scenario where the script can fail while trying to open a file but the file does not exist. In such case you would get FileNotFoundError exception and the worst part is any code after this exception will not be executed

#!/usr/bin/env python3

with open('input.txt', 'r') as myfile:
    for line in myfile:
        print(line)

print('Outside the with block')

Output from this script:
10+ simple examples to learn python try except in detail

As expected we are getting FileNotFoundError exception. So we will handle this by using try..except block:

#!/usr/bin/env python3

try:
    with open('input.txt', 'r') as myfile:
        for line in myfile:
            print(line)
except:
    print('Sorry, file doesn\'t exist')

print('Outside the with block')

I have updated the code, although I have not defined the type of exception and have used a generic except block so for any kind of error I would get "Sorry, file doesn't exist"

Output from this script:

10+ simple examples to learn python try except in detail

So now we don't get any exception and our print statement outside the with block is also executed.

 

Example-2: Provide the type of exception

As I mentioned earlier, in the previous example I have not defined the type of exception so for any kind of issue, I will get the same message which can be misleading. For example the file exist although the user is not having enough permission to access the file and still I would get same message.

For the demonstration, I am using a normal user to execute the same script. I have created input.txt as root user and have given only 600 permission so user 'deepak' has no permission to read this file

[deepak@server ~]$ ls -l input.txt
-rw------- 1 root root 0 Oct 15 14:49 input.txt

Now I execute the same script from Example-1:

[deepak@server ~]$ python3 handle-exceptions.py
Sorry, file doesn't exist
Outside the with block

We still get "Sorry, file doesn't exist" which is misleading because the file is actually there but I don't have permission to access the file.

To handle such situation we can define the Exception Type with except block:

#!/usr/bin/env python3

try:
    with open('input.txt', 'r') as myfile:
        for line in myfile:
            print(line)
except FileNotFoundError:
    print('Sorry, file doesn\'t exist')
except PermissionError:
    print('Sorry, you don\'t have permission to access the file')

print('Outside the with block')

So now I have enhanced the script to handle two separate exceptions for FileNotFoundError and PermissionError.

Output from this script:

10+ simple examples to learn python try except in detail

 

Example-3: Define multiple exceptions in single block

In the previous example we defined separate block for individual exceptions. We can also combine all the applicable exceptions in single except block. For example I have combined FileNotFoundError and PermissionError into single except block and given a more precise print statement:

#!/usr/bin/env python3

try:
    with open('input.txt', 'r') as myfile:
        for line in myfile:
            print(line)
except (FileNotFoundError, PermissionError):
    print('Sorry, file doesn\'t exist or you don\'t have permission to access the file')

print('Outside the with block')

Output from this script:

10+ simple examples to learn python try except in detail

So using this approach saved few lines of code.

 

Example-4: Using a generic exception block

Now we have covered some scenarios where we have manually defined the exception type, but there is also a possibility wherein the exception type doesn't match the ones which we have added in the code in which case it is always a good idea to also add except Exception to handle unforeseen issues. Additionally we can store the output into a variable and then print that variable as the output.

I have updated our script with except Exception block to handle any other exceptions which are not defined in the code and storing the output into error variable, later I will print the content of this variable:

#!/usr/bin/env python3

try:
    with open('input.txt', 'r') as myfile:
        for line in  myfile:
            print(line)
except FileNotFoundError:
    print('Sorry, file doesn\'t exist or you don\'t have permission to access the file')
except Exception as error:
    print(error)
    print(type(error))

print('Outside the with block')

Output from this script:

10+ simple examples to learn python try except in detail

 

try..except..else block

The try…except…else block is a minor modification of the traditional try…except block so that it can include an else block.

Syntax

The syntax for try..except..else block would be:

try:
  # do something here
except [Exception]:
  # If there is Exception, then execute this block.
else:
  # If there are no exceptions then execute this block

The code in the else block is always executed if no error has occurred. So, any code that depends on the try block executing successfully goes in the else block:

 

Example: Using try with else block

In this sample script we will prompt user for two numbers and using the python code we will divide first number by the second number

10+ simple examples to learn python try except in detail

Output from this script:

 ~]$ python3 handle-exceptions.py
Give me two numbers
Enter 'q' to quit

First number: 10
Second number: 5
You get:  2.0

First number: 10
Second number: 0
Traceback (most recent call last):
  File "handle-exceptions.py", line 13, in 
    answer = int(first_num) / int(second_num)
ZeroDivisionError: division by zero

So if we try to divide the "first number" by 0 then we get ZeroDivisionError exception. Let me try to handle ZeroDivisionError with except and else block:

#!/usr/bin/env python3

print("Give me two numbers")
print("Enter 'q' to quit")

while True:
    first_num = input("\nFirst number: ")
    if first_num == 'q':
        break
    second_num = input("Second number: ")
    if second_num == 'q':
        break
    try:
        answer = int(first_num) / int(second_num)
    except ZeroDivisionError:
        print("You can not divide by 0")
    else:
        print('You get: ', answer)

Output from this script:

10+ simple examples to learn python try except in detail

So now the else block is executed for all the SUCCESS condition and except block will handle the ZeroDivisionError exception.

 

try..finally block

We use try..finally when you want exceptions to propagate up but also want to run cleanup code even when exceptions occur. One common usage of try..finally is for reliably closing file handles

Syntax

The syntax to use try..except..finally block would be. The except block is optional and you can also use try..finally without except block.

try:
  # do something here
except [Exception]:
  # If there is Exception, then execute this block.
finally:
   # This is executed always

If you wish to combine else block then the order of the statement should be:

try -> except -> else -> finally

 

Example-1: Using try with finally block

I will take a simple example to help you understand the usage of try..finally block. Here we will prompt user for an input with an integer, next we will divide 100 with this number and store the result in re.

  • Now if an exception is raised then we go into except block
  • If there are no exceptions then else block is executed
  • Irrespective of exceptions, the finally block will always be executed
#!/usr/bin/env python3

try:
    num = int(input("Enter the number: "))
    re = 100/num
except:
    print("Something is wrong")
else:
    print("result is ",re)
finally :
    print("finally program ends")

print('END')

Output from this script (with no exceptions):

~]$ python3 try-finally.py
Enter the number: 10
result is 10.0
finally program ends
END

Output from this script (with exceptions):

~]$ python3 try-finally.py
Enter the number: abcd
Something is wrong
finally program ends
END

So in both the scenarios, the finally block was executed.

 

Example-2: Open and close file handle using try..finally block

This is a more practical example where we are opening a file to perform some read and write operation and intentionally we will try to write invalid utf-8 content which will raise UnicodeDecodeError in which case the finally block will execute and close the file handle.

10+ simple examples to learn python try except in detail

NOTE:

You must call open before the try block because exceptions that occur when opening the file (like OSError if the file does not exist) should skip the finally block entirely:

Output from this script:

~]$ python3 try-finally.py
* Opening file
* Reading data
* Calling close()
Traceback (most recent call last):
  File "try-finally.py", line 11, in 
    handle.read()  # Maybe UnicodeDecodeError
  File "/usr/lib64/python3.6/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte

So even though we have received an exception, our code from finally block was executed to close the file handle.

 

Manually raise exceptions

To trigger exceptions explicitly, you can code raise statements. Their general form is simple—a raise statement consists of the word raise, optionally followed by the class to be raised or an instance of it:

Syntax:

raise instance               # Raise instance of class
raise class                  # Make and raise instance of class: makes an instance
raise                        # Reraise the most recent exception

For example here we have a simple if else condition. If the condition matches then we print something on the console and for else condition we will raise ValueError with some custom message:

#!/usr/bin/env python3

num = int(input('Enter any number: '))
mylist = [10, 21, 34, 49, 52]

if num in mylist:
    print('Bingo, you hit the jackpot')
else:
    raise ValueError('Ohh, you missed the jackpot')

Output from this script:

~]$ python3 raise-exceptions-1.py
Enter any number: 20
Traceback (most recent call last):
  File "raise-exceptions-1.py", line 9, in 
    raise ValueError('Ohh, you missed the jackpot')
ValueError: Ohh, you missed the jackpot

As you see, since the provided number was not part of the mylist, ValueError is raised as we had defined. So using raise we can manually create exceptions within python code.

 

Define and raise custom exceptions

Built-in exceptions cover a wide range of situations. Sometimes, however, you may need to define a custom exception to fit your specific application situation; for example, a MyCustomError exception.

In this case, Python contains the ability to add custom errors by extending the base Exception class. We will use our existing example and instead of ValueError, we will create our own exception and execute it inside the else block:

10+ simple examples to learn python try except in detail

Output from this script when we provide a number which is not present in the list:

 ~]$ python3 raise-exceptions-1.py
Enter any number: 20
Traceback (most recent call last):
  File "raise-exceptions-1.py", line 12, in 
    raise MyCustomError('Ohh, you missed the jackpot')
__main__.MyCustomError: Ohh, you missed the jackpot

 

The assert statement

Python includes the assert statement. The next step toward creating real tests is to assert that a particular comparison holds true. Assertions are typically used to verify program conditions during development. For example, here I am using assert to perform the comparison instead of if condition and raising an exception if condition is not matched

#!/usr/bin/env python3

class MyCustomError(Exception):
    pass

num = int(input('Enter any number: '))
mylist = [10, 21, 34, 49, 52]

try:
    assert num in mylist
    print('Bingo, you hit the jackpot')
except:
    print('Ohh, you missed the jackpot')

Output from this script:

~]$ python3 raise-exceptions-1.py
Enter any number: 20
Ohh, you missed the jackpot

Since the assert condition didn't matched, the except block was executed.

 

Conclusion

In this tutorial, we talked about errors and exceptions, what they are, and how to avoid them. We looked at a few built-in errors and the scenarios that would cause them to be raised. We then moved on to handling them by using try…except and finally blocks. We also covered how to implement our own custom exceptions by using the Exception base class.

This should give you the ability to make your programs more robust by handling both seen and unforeseen issues that may arise during code execution. Handling errors should also help prevent unpleasant usability or security issues from cropping up when your code is in the wild.

Leave a Comment

Please use shortcodes <pre class=comments>your code</pre> for syntax highlighting when adding code.