Python 101: Handling Exceptions

Buffer this pageShare on FacebookPrint this pageTweet about this on TwitterShare on Google+Share on LinkedInShare on StumbleUpon
Reading Time: 8 minutes

 

Handle Exceptions in Python

Hi, and welcome back to Python 101. In this chapter, we will look at how to handle exceptions in Python. Here's an overview of all that we will be covering today:

Programs to whet your appetite

#1 Sum a List of Numbers with Exception Handling

# Sum of 3 numbers
# A simple program of adding 3 given numbers, handling exception in case user inputs anything other than digits.

# asking for inputs
try:
    numberOne = float(input("Please enter the first number: "))
    numberTwo = float(input("Please enter the second number: "))
    numberThree = float(input("Please enter the third number: "))
except ValueError:
    print("That was not a number!")

# displaying total
try:
    print("Total: ", str(numberOne + numberTwo + numberThree))
except NameError:
    print("Cannot compute sum. Please execute the program again.")
Try it here.

#2 Remove comments from a file with Exception Handling

# Removing comments from a file with Exception Handling
# Write a program to remove all the comments from a file. Create a new file and leave the original untampered. 
# Such an activity is usually performed while creating minified version of a script, to reduce file size.

import sys

# ask for file names
inputFileName = input('Please enter the name of the file you wish to remove comments from: ')
outputFileName = input('Please enter the name of the new file: ')

# open both files
try:
    inputFileHandler = open(inputFileName, 'r')
    outputFileHandler = open(outputFileName, 'w')
except FileNotFoundError:
    print("Please specify a valid file. Ensure that the file is located in the same directory as the script.")
    sys.exit()

    # read the file line by line; write to new file as it is if no comment in line; modify and then write to new file if comment present
# find() returns the position of a character/substring in a string; returns -1 if not found
# line[0: positionOfHash] slices the line till the character just behind the # symbol. In the process, the new line character after the comment is also deleted, so we manually add it here
for line in inputFileHandler.readlines():
    positionOfHash = line.find('#')

    if positionOfHash != -1:
        line = line[0 : positionOfHash]
        line = line + "\n"

    outputFileHandler.write(line)

inputFileHandler.close()
outputFileHandler.close()

# printing a success message
print(outputFileName,"has been created without comments.")


######## END OF PROGRAM ########

# If you are running on an online environment such as repl.it, and don't have a sample file at hand, uncomment the following to create a sample file.

##fileHandler2 = open('dev_script.py', 'w+')
##fileHandler2.write('myInt = 4						# an integer variable\n')
##fileHandler2.write('myString = \"Ethan\"					# a string variable\n\n')
##fileHandler2.write('myList = [1, 2, 3, 4, 5, 6]				# a list variable\n')
##fileHandler2.write('mySet = set(myList)			# creating a set from a list\n')
##fileHandler2.write('myTuple = 2, 3				# creating a tuple without parentheses\n')
##fileHandler2.write('myDict = {1: \'one\', 2: \'two\'}		# creating a dictionary variable')
##fileHandler2.seek(0)
##print(fileHandler2.read())
Try it here.

Exception Handling

There are instances when your code doesn't go as planned. Let's take a couple of examples which every programmer comes across.

>>> total = 100
>>> "Result: " + total
Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    "Result: " + total
TypeError: Can't convert 'int' object to str implicitly.


>>> marks*2
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    marks*2
NameError: name 'marks' is not defined


>>> fh = open("fileOne.py")
Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    fh = open("fileOne.py")
FileNotFoundError: [Errno 2] No such file or directory: 'fileOne.py' 

In general speaking sense, exceptions are instances that do not conform to a general rule. In programming sense, the problematic situation (a.k.a exception) is not a frequent occurrence, it is only an exception to the general flow of the program. Your code doesn't perform as you expect. It could be due to a mathematical anomaly, or wrong input by user, or even a syntactical error.

You will have noticed that a majority of these errors are suffixed by the word Error and not by Exception as in Java. This is because the Error is encountered by the program because of the exception to general flow. So Python is right in saying that an Error has occurred. That said, there are cases when these exceptions are not errors, e.g. SystemExit, StopIteration, KeyboardInterrupt etc. These are also exceptions, and the word Error in actual errors highlights the difference.

Okay, so how to get around these Errors? Like other modern languages, Python provides a mechanism to get by in these situations. You can wrap the statements that are likely to be problematic in a try clause, and provide an elegant message (or alternative statements) to the user in the except clause.

>>> try:
	fh = open("fileOne.py")
except FileNotFoundError:					# hit backspace to go back a tabspace
	print("Please specify a valid file.")

	
Please specify a valid file.

A try clause may or may not have more than one except clauses, for handling multiple types of Exceptions, as we will see in the later sections. If there are multiple except clauses, and if the try clause indeed throws multiple exceptions, then the except block corresponding to the first exception will be executed.

A generic except clause (except: ) i.e. which does not specify the type of Exception after the except keyword catches all types of Exceptions. We will see this in the later sections.


How try-except works

  • Python 'tries' to execute statements in the try clause.
  • If no exception(s) occurs, the except clause is skipped after the statements in try clause are executed.
  • If one of the statements in try block triggers an exception, then the rest of the try clause is skipped, and control is moved to except clause(s).
  • If the type of Exception matches the Exception name after the except keyword(if provided), then that except clause is executed, and execution continues to the statements after the try-except clauses.
  • If the type of Exception does not match the Exception name after the except keyword, then the outer try clause (in the event it is a nested try-except system i.e. clauses in the order of try-try-except-except or even further level) is checked to see if it has any except clause matching the Exception name.
  • If there is no except clause matching the thrown Exception, and there is no generic except clause either, then the execution of the program stops with the console printing the Error name along with its description, such as 'NameError: name 'marks' is not defined'.

Handling Multiple Exceptions

There may be more than one statements in the try clause which are likely to throw an exception. To handle such situations, you can define multiple except clauses for each kind of exception that is likely to arise.

Bear in mind, that at most 1 of these except clauses will execute, which will correspond to the first problematic statement.

Also, it does not matter in which order you specify the except clauses, as demonstrated below.

>>> try:
	marks = 100
	divide = 15/2
	fh = open('someExistentFile.txt', 'r')
	print("Total marks:", marks)
except FileNotFoundError:
	print("Caught FNF Error.")
except NameError:
	print("Caught NameError.")
except ZeroDivisionError:
	print("Caught ZD Error.")
	
Total marks: 100


>>> del marks		# removing already present variable from the memory
>>> try:
	divide = 15/2
	fh = open('someExistentFile.txt', 'r')
	print("Total marks:", marks)
except FileNotFoundError:
	print("Caught FNF Error.")
except NameError:
	print("Caught NameError.")
except ZeroDivisionError:
	print("Caught ZD Error.")
	
Caught NameError.



>>> try:
	divide = 15/2
	fh = open('someNonExistentFile.txt', 'r')
	print("Total marks:", marks)
except FileNotFoundError:
	print("Caught FNF Error.")
except NameError:
	print("Caught NameError.")
except ZeroDivisionError:
	print("Caught ZD Error.")
	
Caught FNF Error.



>>> try:
	divide = 15/0
	fh = open('someNonExistentFile.txt', 'r')
	print("Total marks:", marks)
except FileNotFoundError:
	print("Caught FNF Error.")
except NameError:
	print("Caught NameError.")
except ZeroDivisionError:
	print("Caught ZD Error.")
	
Caught ZD Error.

Alternatively, an except clause may have multiple exceptions in the form of a tuple.

>>> try:
	divide = 15/2
	fh = open('someNonExistentFile.txt', 'r')
	print("Total marks:", marks)
except (FileNotFoundError, NameError, ZeroDivisionError):
	print("Caught an error, not sure which one though.")

	
Caught an error, not sure which one though.


# To make out which exception was actually caught, you can use an alias for the exception and apply the builtin method 'repr()' on it to get its name, along with its description. The repr() method is explained in the 'Few General Things' section down below.
>>> try:
	divide = 15/2
	fh = open('someNonExistentFile.txt', 'r')
	print("Total marks:", marks)
except (FileNotFoundError, NameError, ZeroDivisionError) as error:
	print("Caught an error:", repr(error))

	
Caught an error: FileNotFoundError(2, 'No such file or directory')

Generic Except clause

Instead of defining an except clause for each type of exception that might occur, Python allows you to define a single except clause which can be used to catch any exception. This can be used in conjunction with clauses which catch only a specific kind of Exception.

>>> try:
	divide = 15/2
	fh = open('someNonExistentFile.txt', 'r')
	print("Total marks:", marks)
except:
	print("Caught an error, not sure which one though.")

	
Caught an error, not sure which one though.

# in conjunction with Exception-specific except clause
>>> try:
	divide = 15/2
	fh = open('someNonExistentFile.txt', 'r')
	print("Total marks:", marks)
except ZeroDivisionError:
	print("Caught ZD Error.")
except:
	print("Caught an error, not sure which one though.")

	
Caught an error, not sure which one though.

# In order to identify the caught exception, you can use the following method. The Exception class is the base class of all exceptions (e.g. FileNotFoundError, ZeroDivisionError etc.). That is to say, that all the exceptions we know of, are actually derived from Exception class. In case you are not familiar with classes and objects, which you shouldn't be if you are a beginner, you can skip this for now.
# So, 'except:' is as good as 'except Exception:'. Then, we give it an alias on which we supply to the builtin method repr(), which gives us the name of the caught exception, along with its description. The repr() method is explained in the 'Few General Things' section down below.
>>> try:
	divide = 15/2
	fh = open('someNonExistentFile.txt', 'r')
	print("Total marks:", marks)
except ZeroDivisionError:
	print("Caught ZD Error.")
except Exception as err:
	print("Caught an error:", repr(err))

	
Caught an error: FileNotFoundError(2, 'No such file or directory')

Ignoring Exceptions: the pass keyword

To ignore an exception, you can use the pass keyword. Since you cannot leave a clause empty even when you don't want Python to do anything, the pass keyword comes in really handy. This is particularly useful when you don't want to display the traceback info on the screen.

>>> try:
	divide = 15/2
	fh = open('someNonExistentFile.txt', 'r')
	print("Total marks:", marks)
except:
	pass

# NO OUTPUT
 

Specifying clean-up actions: the finally keyword

In addition to the try and except clauses, there is an optional finally clause, which is executed regardless whether an exception is thrown or not, and also whether it is caught or not. This clause is primarily used for releasing external resources such as open files or sockets. For example, even if the purpose of reading a file was successful or not, it still needs to be closed in the end.

If a try clause throws an exception and it is handled by the except clause, then the except clause is executed first and then the finally clause. See snippets #1 & #2 below for examples.

In the event that an exception occurs in the try clause and is not handled in the except clause, it is raised after the finally clause has finished executing. See code snippet #3 below for example.

Furthermore, this optional clause, when defined, is executed when the try-except-finally clauses are in a function and the return statement lies in the try clause or even except clause. But the finally clause is executed after the return statement. And if there is a return statement is also present in the finally clause, then that return statement is taken as the eventual return statement. The examples down below will help, snippets #4 to #7.

The finally clause is executed even when the try clause is exited via control statements such as break, continue. See snippets #8 & #9 below for examples. If you are not familiar with these control statements, here's a link to Chapter 3.

# Without the finally clause					CODE SNIPPET #1
>>> try:
	fh = open('someExistentFile.txt', 'r')
	fh.write('Trying to write to a file opened in reading mode....')
except Exception as error:
	print(repr(error))

	
UnsupportedOperation('not writable',)
>>> fh.closed
False


# With the finally clause, and exception is caught		CODE SNIPPET #2
>>> try:
	fh = open('someExistentFile.txt', 'r')
	fh.write('Trying to write to a file opened in reading mode....')
except Exception as error:
	print(repr(error))
finally:
	fh.close()
	print("File closed.")

	
UnsupportedOperation('not writable',)
File closed.
# When the exception is not handled, the finally clause is executed first and then the uncaught exception is printed in the traceback.				CODE SNIPPET #3
>>> try:
	divide = 4/0
except FileNotFoundError:
	pass
finally:
	print("Executing finally.")

Executing finally.
Traceback (most recent call last):
  File "<pyshell#331>", line 2, in <module>
    divide = 4/0
ZeroDivisionError: division by zero

>>> fh.closed
True

# FINALLY INSIDE A FUNCTION
# The finally clause is executed even when the return statement is in the try clause. The order is: finally clause first, then the return statement.			CODE SNIPPET #4
>>> def anyFunction():
	try:
		var = 10
		#bunch of statements
		return 5
	except:
		pass
	finally:
		print("executing finally inside a function even when there is a return statement in the try clause.")
	
>>> anyFunction()
executing finally inside a function even when there is a return statement in the try clause.
5

# If there is a return statement in both the try and finally clauses, then the return statement in the finally clause is the final return statement.			CODE SNIPPET #5
>>> def anyFunction():
	try:
		var = 10
		#bunch of statements
		return 5
	except:
		pass
	finally:
		return 10
	
>>> anyFunction()
10

# When there is a return statement in the except clause and an exception is caught, the finally clause is executed first and then the return statement in except clause.			CODE SNIPPET #6
>>> def anyFunction():
	try:
		divide = 4/0
	except:
		print("except clause.")
		return 10
	finally:
		print("finally clause.")
		
>>> anyFunction()
except clause.
finally clause.
10

# When there is a return statement in the except clause as well as in finally clause, the return in except clause is treated as the final return statement. So, the order is: except-finally.	CODE SNIPPET #7
>>> def anyFunction():
	try:
		divide = 4/0
	except:
		print("except clause.")
		return 10
	finally:
		print("finally clause.")
		return 5
	
>>> anyFunction()
except clause.
finally clause.
5

# FINALLY with CONTROL STATEMENTS: break, continue
# In case you are not familiar with these control statements, I urge you to check out Chapter 3 @ https://www.djangospin.com/python-101/python-101-loops/#break-and-continue. The crux of it is as follows:
# break: The break statement takes the control out of the loop and onto the statement that follows after the loop.
      while predicate:                            for alias in sequence:
           while loop body                               for body loop
           if predicate:                                 if predicate:
--------------- break                       ----------------  break
|          while loop body                  |            for body loop
|                                           |
--->  more statements after while loop      --->  more statements after for loop

# continue: The continue statement skips the current iteration and begins the next iteration i.e.

--->  while predicate:                      --->  for alias in sequence:
|          while loop body                  |            for body loop
|          if predicate:                    |            if predicate:
--------------- continue                    ----------------  continue
           while loop body                               for body loop
                                              
      more statements after while loop            more statements after for loop

# finally with break						# CODE SNIPPET #8
>>> try:
	i = 2
	while i < 10:
		print("Value of i:", i)
		i = i + 1
		if i == 5:
			print("Breaking out of the loop.")
			break
except:
	pass
finally:
	print("Executing finally clause.")
	
Value of i: 2
Value of i: 3
Value of i: 4
Breaking out of the loop.
Executing finally clause.

# finally with continue
>>> try:									# CODE SNIPPET #9
	i = 0
	while i < 10:
		i = i + 1
		if i % 2 == 0:			# skip even numbers, continue with next iteration
			continue
		print("Value of i:", i)
except:
	pass
finally:
	print("Executing finally clause.")
	
Value of i: 1
Value of i: 3
Value of i: 5
Value of i: 7
Value of i: 9
Executing finally clause.

The else clause

The last piece of exceptional handling constructs is the else clause.

The else clause is optional, and if defined, it must follow all the except clauses, and precede the finally clause. The order of clauses is try-except-else-finally.

It is used to write code which must be executed if the try clause does not throw any exception AND before the finally clause. See code snippets #1 & #2 for examples.

So what is the purpose of the else clause? The answer is, that it avoids accidentally catching an exception that wasn't thrown by the code in the try clause. Another use of the else clause is that it helps to write the exceptional and non-exceptional code at the same level of indentation, which helps readability.

It is possible to include the code that we want in the else block, in the try clause instead, because it will run fine if there were no exceptions raised by it. But, in case it did raise an exception and that too, one we were already handling, we would not know. Leaving it in the try clause will only make the code ambiguous, which does not go well with Python's Zen. See code snippets #3 & #4 below for examples.

Use of the else clause in exception handling is somewhat rare, but the construct is present in the language for a reason.

If there is a return statement in both the else clause and the finally clause, the one in finally clause gets evaluated. See code snippet #5 below for example.

# Using the else clause					# CODE SNIPPET #1
>>> try:
	fh = open('someExistentFile.txt', 'r')
except FileNotFoundError:
	print("The file does not exist.")
else:
	print("The file exists.")
	print("Proceeding with reading operations.")
finally:
	print("Closing the file, if it opened.")
	fh.close()

	
The file exists.
Proceeding with reading operations.
Closing the file, if it opened.

>>> try:							# CODE SNIPPET #2
	fh = open('someNonExistentFile.txt', 'r')
except FileNotFoundError:
	print("The file does not exist.")
else:
	print("The file exists.")
	print("Proceeding with reading operations.")
finally:
	print("Closing the file, if it opened.")
	fh.close()

	
The file does not exist.
Closing the file, if it opened.


# else clause helps in make the code clear, clear the ambiguity
>>> try:							# CODE SNIPPET #3
	fh = open('someExistentFile.txt', 'r')
	fh2 = open('someNonExistentFile.txt', 'r')
except FileNotFoundError:
	print("FNF! Not sure which one though...")

	
FNF! Not sure which one though...

>>> try:							# CODE SNIPPET #4
	fh = open('someExistentFile.txt', 'r')
except FileNotFoundError:
	print("FNF!")
else:
	fh2 = open('someNonExistentFile.txt', 'r')

	
Traceback (most recent call last):
  File "<pyshell#429>", line 6, in <module>
    fh2 = open('someNonExistentFile.txt', 'r')
FileNotFoundError: [Errno 2] No such file or directory: 'someNonExistentFile.txt'


# finally with else					# CODE SNIPPET #5
>>> def anyFunction():
	try:
		pass
	except:
		pass
	else:
		return 2
	finally:
		return 10

	
>>> anyFunction()
10
 

Raising your own Exceptions: the raise keyword

The raise keyword is used to explicitly raise an exception. This is in contrast to when you make a mistake in your code, because then the exception is raised implicitly. Here, you are deliberately raising an exception.

The raise keyword is useful in 2 scenarios, one is for reraising the exception, and other is for using exception for error-checking.

 

Reraising an exception: raise

The raise keyword in this situation is found in the except clause, as a standalone keyword. This is used when you want to do some processing in the except clause before you re-raise the most recently caught exception, also known as active exception.

>>> import io
>>> try:
	fh = open('someExistentFile.txt', 'r')
	fh.write("Attempting to write to a file opened in read-only mode.")
except io.UnsupportedOperation:
	fh.close()
	print("File closed?", fh.closed)
	raise

File closed? True
Traceback (most recent call last):
  File "<pyshell#292>", line 3, in <module>
    fh.write("Attempting to write to a file opened in read-only mode.")
io.UnsupportedOperation: not writable

 

Error checking: raise ExceptionName("Optional message string.")

You can intentionally raise errors as part of error-checking. The raise keyword is followed by the Exception to be thrown if a particular check fails. You can even pass a custom message to provide a situation-specific explanation to the user.

>>> temperature = 450
>>> if temperature > 400:
	raise ValueError()

Traceback (most recent call last):
  File "<pyshell#257>", line 2, in <module>
    raise ValueError()
ValueError
>>> 
>>> 
>>> 
>>> if temperature > 400:
	raise ValueError("Temperature greater than 400 degrees!!! CODE GREEN! CODE GREEN!")

Traceback (most recent call last):
  File "<pyshell#262>", line 2, in <module>
    raise ValueError("Temperature greater than 400 degrees!!! CODE GREEN! CODE GREEN!")
ValueError: Temperature greater than 400 degrees!!! CODE GREEN! CODE GREEN!

You can choose from common builtin Exceptions and just supply a custom message string, as we did in the above example. And if there is no suitable builtin Exception, you can make your own exception in the following fashion:

# creating an exception object from an existing Exception type

>>> TemperatureError = ValueError()
>>> raise TemperatureError
Traceback (most recent call last):
  File "<pyshell#220>", line 1, in <module>
    raise TemperatureError
ValueError



>>> TemperatureError = ValueError("Temperature greater than 400 degrees!!! CODE GREEN! CODE GREEN!")
>>> raise TemperatureError
Traceback (most recent call last):
  File "<pyshell#246>", line 1, in <module>
    raise TemperatureError
ValueError: Temperature greater than 400 degrees!!! CODE GREEN! CODE GREEN!




>>> def check_temperature(temperature):
	if temperature < 45:
		raise TemperatureError
	print("Temperature under control.")

	
>>> check_temperature(450)
Traceback (most recent call last):
  File "<pyshell#249>", line 1, in <module>
    check_temperature(450)
  File "<pyshell#248>", line 3, in check_temperature
    raise TemperatureError
  File "C:\Python34\lib\idlelib\run.py", line 353, in runcode
    exec(code, self.locals)
  File "<pyshell#246>", line 1, in <module>
    raise TemperatureError
ValueError: Temperature greater than 400 degrees!!! CODE GREEN! CODE GREEN!

Note that even though you are raising TemperatureError, the exception that is raised is ValueError. This is because all Exceptions are actually classes (parent of all these is the class called Exception), and classes can be instantiated i.e. objects can be made out of them. The very first line of the example (TemperatureError = ValueError()) is creating an instance/object called TemperatureError of the class ValueError. If you wish to create your own Exception class, you can do that in the following way. It is a brief write-up, which can be extended based on your knowledge of object-oriented concepts.

# creating custom Exception class derived from the parent class of all Exception classes i.e. Exception.
>>> class TemperatureError(Exception): pass

>>> myCustomExceptionObject = TemperatureError("Temperature greater than 400 degrees!!! CODE GREEN! CODE GREEN!")
>>> def check_temperature(temperature):
	if temperature > 400:
		raise myCustomExceptionObject
	print("Temperature under control.")

	
>>> check_temperature(450)
Traceback (most recent call last):
  File "<pyshell#309>", line 1, in <module>
    check_temperature(450)
  File "<pyshell#308>", line 3, in check_temperature
    raise myCustomExceptionObject
TemperatureError: Temperature greater than 400 degrees!!! CODE GREEN! CODE GREEN!
Note that some other languages like Java use the keyword throw instead of raise for the same functionality.

A Few General Things

repr()

In the last chapter, we learnt about the repr() method, and in the Specifying clean-up actions: the finally keyword section, we saw that repr(error) gave us the name of the caught exception along with its description. That's because, a class can control what this function returns for its instances by defining a __repr__() method, and each of the Exception classes have got this defined. You will note that str(error) gives you just the description. That's because each of the Exception classes have defined a __str__() method, which states just the description of the Exception.

>>> try:
	fh = open('someExistentFile.txt', 'r')
	fh.write('Trying to write to a file opened in reading mode....')
except Exception as error:
	print(str(error))

	
not writable

>>> try:
	fh = open('someExistentFile.txt', 'r')
	fh.write('Trying to write to a file opened in reading mode....')
except Exception as error:
	print(repr(error))

	
UnsupportedOperation('not writable',)

 

Nested Try-Except

In the How try-except works section, we touched upon nested try-except clauses in the second last point. Here's an example of nested try-except clauses.

>>> try:
	a = 50
	try:
		fh = open('someNonExistentFile.txt', 'r')
	except ValueError:
		print("No handler for FileNotFoundError in the INNER except clause(s).")
except ValueError:
	print("No handler for FileNotFoundError in the OUTER except clause(s).") 

If two nested handlers exist for the same exception, and the exception occurs in the try clause of the inner handler, the outer handler will handle the exception IF AND ONLY IF there is no matching or generic handler in the inner except clause(s). If there is a matching or generic except clause in the outer except clause(s), then it will handle the exception, else it (the outermost except mechanism) will throw the corresponding error. Consider the following examples.

# neither matching except clause nor generic except clause in outer except clause(s)
>>> try:
	a = 50
	try:
		fh = open('someNonExistentFile.txt', 'r')
	except ValueError:
		print("No handler for FileNotFoundError in the INNER except clause(s).")
except ValueError:
	print("No handler for FileNotFoundError in the OUTER except clause(s).")
	
Traceback (most recent call last):
  File "<pyshell#160>", line 4, in <module>
    fh = open('someNonExistentFile.txt', 'r')

# matching except clause in inner except clause(s)
>>> try:
	a = 5
	try:
		fh = open('someNonExistentFile.txt', 'r')
	except FileNotFoundError:		
		print("File not found. Caught in INNER except clause(s).")
except:
	print("File not found. Caught in OUTER except clause(s).")

	
File not found. Caught in INNER except clause(s).





# generic except clause in inner except clause(s)
>>> try:
	a = 5
	try:
		fh = open('someNonExistentFile.txt', 'r')
	except:
		print("File not found. Caught in INNER except clause(s).")
except:
	print("File not found. Caught in OUTER except clause(s).")

	
File not found. Caught in INNER except clause(s).





# matching except clause in outer except clause(s)
>>> try:
	a = 5
	try:
		fh = open('someNonExistentFile.txt', 'r')
	except ValueError:
		print("File not found. Caught in INNER except clause(s).")
except FileNotFoundError:
	print("File not found. Caught in OUTER except clause(s).")

	
File not found. Caught in OUTER except clause(s).






# generic except clause in outer except clause(s)
>>> try:
	a = 5
	try:
		fh = open('someNonExistentFile.txt', 'r')
	except ValueError:
		print("File not found. Caught in INNER except clause(s).")
except:
	print("File not found. Caught in OUTER except clause(s).")

	
File not found. Caught in OUTER except clause(s).

 

Prompting user till a valid input is provided

You can combine the while loop, the break control statement and the try-except clauses to prompt a user till a valid input is provided. As soon as a valid input is detected, the break takes the control out of the while loop and onto the code succeeding it.

>>> while True:
	try:
		filename = input("Please enter the file name you wish to manipulate: ")
		fh = open(filename, 'r')
		break
	except FileNotFoundError:
		print("File not found. Please ensure that the file exists, and is located in the current directory.")

		
Please enter the file name you wish to manipulate: someNonExistentFile.txt
File not found. Please ensure that the file exists, and is located in the current directory.
Please enter the file name you wish to manipulate: someExistentFile.txt

 

Exiting a program using sys.exit()

To exit a script, you can use the exit() method of the sys module.

This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored.

~ Python documentation


Further Reading


Exercises

As of now, each of our 2 programs have to be restarted if there is invalid input from the user. Your task is to make the programs more user-friendly by prompting the user up until the time he enters valid values.


What Next?

Congratulations! You have made it through to the end of Python 101 course. We went over all the basic concepts, and few intermediate ones too. You are now in a position to take up advanced topics in Python. You can go in several directions from here, as I mentioned in the introduction to this course: Systems Programming with Python, Desktop apps with Tkinter in Python, Game Development with Pygame, Internet Programming with Python among other avenues. But for a few of these, elementary knowledge of Object Oriented Python is required, so I suggest you take that up first. Following is link to Object Oriented Python as well as some other helpful articles.

 

 


Buffer this pageShare on FacebookPrint this pageTweet about this on TwitterShare on Google+Share on LinkedInShare on StumbleUpon

Leave a Reply