CHAPTER 10

Handling Errors

In this chapter, you learn how to handle errors in Python. First, we quickly review the different types of errors that occur in computer code and the ways you can catch the different types. We then focus on using try… except blocks to handle errors in your Python code. You learn to cause errors, trap exceptions, and create custom exceptions.

Snapshot of handling errors.

Understanding the Various Types of Errors

Identify Common Python Errors

Meet the try… except Block

Cause Errors and Trap Exceptions

Raise an Exception Manually

Add an else Block or a finally Block

Create Nested try… except Blocks

Create Custom Exceptions

Understanding the Various Types of Errors

In this section, you learn about the different types of errors that can occur in code, what causes them, and what you can do to eliminate them.

We start with compile-time errors, errors that occur when Python is unable to create workable instructions from the commands in a script. Many compile-time errors are syntax errors, mistakes in the structure of the code. We then move on to runtime errors, errors that occur after Python has compiled a script successfully and has moved on to executing it. Runtime errors include semantic errors and logical errors.

Compile-Time Errors

Python is generally considered an interpreted language, which is often understood to mean that it is not a compiled language. But the difference between interpreted computing languages and compiled computing languages is not clear cut, and Python does perform compilation.

Before running a script, Python compiles it to a form called byte code, interpreting the commands the script contains and creating from them instructions that the computer can execute. The instructions need to be specific to the computer’s operating system, such as Windows or macOS, and to the processor type, such as Intel or Apple Silicon.

A compile-time error occurs when the script’s commands are incomplete, incorrect, or otherwise will not work. A compile-time error occurs before the script runs, so Python does not run the script. You need to fix the problem in order to make the script run.

Runtime Errors

After compiling the code in the script, Python tells the computer to run the script. At this point, you may get a runtime error — an error that occurs while the code is running, as opposed to while the code is being compiled.

A runtime error may manifest itself as an exception that stops the script from running and causes Python to display an error message. Alternatively, the script may freeze or crash, it may return an unexpected result, or it may damage data.

Syntax Errors

A syntax error, also called a syntactical error, is an error where the problem lies in the structure of the code statements. Syntax errors have various causes, including the following:

  • Straightforward typos, such as the wrong character, missing punctuation, or an extra space
  • Missing required elements of a statement
  • Extra, and incorrect, elements of a statement
  • Confusion about variables, such as unintentionally creating the new variable firstname when you mean to reassign the existing variable firstName

Python itself or your code editor may be able to identify a syntax error for you. For example, the illustration shows Python flagging the cause of a syntax error in the following statement, which contains an extra comma after the "Bill" item in the list. The caret (A) points to the problem, and the SyntaxError statement (B) briefly explains what is wrong.

a = ["Ann", "Bill",, "Chris"]

Snapshot of Python flagging.

Semantic Errors

A semantic error is an error in which your code is syntactically correct but does not execute the way you intend it to. The word semantic means “related to meaning in language or logic” — in other words, the meaning of the code is wrong.

For example, if a script gets stuck in an infinite loop because the break statement you included never gets triggered, you have likely committed a semantic error. Similarly, if a while loop never runs because its condition cannot be met, that might be a semantic error.

Your code editor or IDE will typically not catch semantic errors. Instead, you will normally discover them while testing and debugging your scripts.

How you discover semantic errors will vary depending on the error’s effects. Continuing the previous example, you will notice an infinite loop quickly, because the script will not finish and you will need to break out of the loop. By contrast, a while loop that never runs may be less obvious.

Logical Errors

A logical error occurs when you, the developer, have told the script to take the wrong action. Even though the script is syntactically correct and semantically correct, what the script does is incorrect. For example, a logical error might occur if you make a mistake with operator precedence when performing calculations or if you use integer division where you should use floating-point division.

Identify Common Python Errors

Python includes a wide variety of built-in exceptions for handling types of errors that occur frequently. For example, a SyntaxError error occurs when Python’s parser encounters syntax it cannot convert into valid code, such as when you omit a comma or include an extra parenthesis. A TypeError error occurs when the code specifies the wrong type of object for an operation, such as trying to add an integer and a string. A ValueError error occurs when the code specifies the correct type of object but an incorrect value, such as trying to return the square root of a negative number.

Table 10-1 explains common error types in Python.

Table 10-1: Common Errors in Python

Exception

Occurs When

AssertionError

An assert statement fails. An assert statement is a tool used for debugging code.

AttributeError

An attribute assignment or attribute reference is incorrect.

EOFError

The input() function reaches the end-of-file condition.

FloatingPointError

An error occurs in a floating-point calculation.

GeneratorExit

Code calls the close() method of a generator.

ImportError

Importing the specified module fails.

IndexError

The index number of a sequence is out of range.

KeyError

The specified key is not in the dictionary.

KeyboardInterrupt

The user gave a keyboard interrupt by pressing Ctrl + C or Del.

MemoryError

An operation runs out of memory.

ModuleNotFoundError

Python cannot find the specified module.

NameError

The specified variable is not found.

NotImplementedError

An abstract method requires a derived class to override the method; or a developer uses this error as a placeholder to show a real implementation is still needed.

OSError

An operating system–related error occurs.

OverflowError

An arithmetic operation returns an error too large to represent.

ReferenceError

A weak reference proxy accesses an attribute of an item that has been garbage collected.

RuntimeError

A runtime error occurs that does not fall into any other category.

StopIteration

The next() function finds no further items in the iterator to return.

SyntaxError

The parser encounters a syntax error.

IndentationError

The indentation level of a statement is incorrect — for example, some indentation is missing.

TabError

The indentation consists of a mixture of tabs and spaces instead of only tabs or only spaces.

SystemError

An internal error occurs in the Python interpreter.

SystemExit

The sys.exit() method runs.

TypeError

An object is of the wrong type for the specified operation.

UnboundLocalError

A function or method refers to a local variable that has no value.

UnicodeError

Encoding or decoding Unicode characters causes an error.

UnicodeEncodeError

Encoding Unicode characters causes an error.

UnicodeDecodeError

Decoding Unicode characters causes an error.

UnicodeTranslateError

A Unicode-related error occurs during translation.

ValueError

An argument passed to a function or method has the correct type but an incorrect value.

ZeroDivisionError

Division or modulo by zero is attempted.

Meet the try… except Block

Python uses a type of object called an exception to handle errors. Python includes many built-in exceptions, which are all derived from the same base class of exception. For example, using the wrong name may cause a NameException exception, whereas supplying the wrong kind of value may cause a ValueException exception.

When an error occurs, Python raises or throws an exception. You can catch or trap an exception so that you can determine what has gone wrong and do something about it.

Python’s tool for handling exceptions is the try… except block, which looks like the following pseudocode. Italics indicate placeholders, and the sections in brackets are optional.

try:

statements1

[except error:

statements2]

except:

statements3

[else:

statements4]

[finally:

statements5]

Here is how the try… except block works:

  • try:. This keyword starts the try block.
  • statements1. This block contains one or more statements that may cause an exception. The try block is said to wrap these statements.
  • except error:. The except keyword starts an except block for the specified error. For example, except NameError: starts an except block that controls what happens when a NameError error occurs.
  • statements2. This block contains one or more statements to run when the specified error occurs.
  • except:. The except keyword without a specific error starts an except block for any error.
  • statements3. This block contains one or more statements to run when any error occurs.
  • else:. The else keyword starts a block specifying what to do if no error has occurred.
  • statements4. This block contains one or more statements to run if no error has occurred.
  • finally:. This keyword starts a block specifying what to do after the rest of the try… except block has completed, whether an error has occurred or not.
  • statements5. This block contains one or more statements to run after execution reaches the finally keyword.

The following subsections contain brief examples of try… except blocks.

Trap Any Exception

If you just want to trap any exception that Python raises, you can use a plain except statement, as in the following example:

try:

x = 5/0

except:

print("An error occurred.")

Trap One or More Particular Exceptions

A generic error message offers little help, so you will often do better to trap one or more specific exceptions that are likely to occur, as in the following example:

try:

x = 5/0

except(NameError):

print("A name is missing.")

except(ZeroDivisionError):

print("A divide-by-zero error occurred.")

except:

print("An error occurred.")

This example contains three except blocks:

  • except(NameError):. This block catches NameError, the type of error that occurs when your code specifies an item that does not exist.
  • except(ZeroDivisionError):. This block catches ZeroDivisionError, the error that occurs when your code tries to divide by zero. As the code stands, the x = 5/0 statement triggers a ZeroDivisionError error.
  • except:. This block catches any other errors.

The unqualified except block must be the last except statement in the try… except block. You cannot use except with a specific error after an unqualified except block. Doing so causes the error SyntaxError: default 'except:' must be last.

Add an else Block

Python supports adding an else block to a try… except block. Here is an example:

try:

x = 5/0

except:

print("An error occurred.")

else:

print("No error occurred.")

An else block can be useful, but many try… except blocks do not need one.

Add a finally Block

You can include a finally block in your try… except blocks to specify an action that Python should always perform, whether or not an exception has occurred. Here is an example:

try:

x = 5/0

except:

print("An error occurred.")

finally:

print("The try block has finished.")

Cause Errors and Trap Exceptions

In this section, you cause errors in your code deliberately and observe the exceptions that Python throws as a result. You then handle the exceptions by using try… except blocks. The first try… except block you create is generic, returning the same error message for every exception it catches. After that, you create a more sophisticated try… except block that displays specific error messages for the exceptions you raised earlier, plus a generic error message for any other exception.

Cause Errors and Trap Exceptions

“Snapshot of cause errors and create a generic exception trap.”

Cause Errors and Create a Generic Exception Trap

001.eps Open a terminal window and launch Python.

dga.eps The Python prompt appears.

002.eps Type the following statement, which creates the variable x and assigns to it the result of 5 divided by 0. Press Ent.

x = 5/0

An error occurs.

dgb.eps Python displays the exception for the error:

ZeroDivisionError: division by zero

003.eps Type the following statement, which assigns to x the value of variable y, and then press Ent.

x = y

Snapshot of python displays the exception for the error.

An error occurs, because y does not yet exist.

dgc.eps Python displays the exception for the error:

NameError: name 'y' is not defined

004.eps Type the following try… except block, which uses a single unspecified exception. Press Ent at the end of each line, and press Ent again at the end.

try:

x = 5/0

except:

"An error occurred."

dgd.eps Python returns 'An error occurred.' because the try block catches the error.

Snapshot of trap specific errors.

Trap Specific Errors

001.eps In the same terminal window, type the following try… except block, which includes specific messages for the ZeroDivisionError exception and the NameError exception you raised earlier. Press Ent at the end of each line.

try:

x = 5/0

except(ZeroDivisionError):

"A divide-by-zero error occurred."

except(NameError):

"A name is missing."

except:

"An error occurred."

002.eps Press Ent to end the block.

dge.eps Python returns the message 'A divide-by-zero error occurred.', because except(ZeroDivisionError) catches the error.

Snapshot of python returns the message.

003.eps Type the same try… except block, but this time include x = y to produce the NameError exception. Press Ent at the end of each line.

try:

x = y

except(ZeroDivisionError):

"A divide-by-zero error occurred."

except(NameError):

"A name is missing."

except:

"An error occurred."

004.eps Press Ent to end the block.

dgf.eps Python returns the message 'A name is missing.', because the except(NameError) catches the error.

Raise an Exception Manually

In the previous section, “Cause Errors and Trap Exceptions,” you caused the ZeroDivisionError and NameError errors deliberately by entering statements guaranteed not to work. This approach is straightforward for some errors, but you might need to get creative to produce other errors. So Python offers an alternative: You can raise specific exceptions manually to test your code.

To raise an exception, you use the raise command and specify the type of exception — for example, raise Exception or raise RuntimeError. You can also specify the text to display to the user when the exception or error is raised.

Raise an Exception Manually

“Snapshot of raise an exception outside of a try except block.”

Raise an Exception Outside of a try… except Block

001.eps Open a terminal window and launch Python.

dga.eps The Python prompt appears.

002.eps Type the following statement, which uses the raise keyword to raise a ValueError error with a custom message. Press Ent.

raise ValueError("This value is not valid.")

dgb.eps Python returns the following:

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

ValueError: This value is not valid.

“Snapshot of raise an exception inside of a try except block.”

Raise an Exception Inside of a try… except Block

001.eps Still in the same terminal window and Python session, type the following try block, which contains a statement that raises a TypeError. Press Ent at the end of each line.

try:

raise TypeError

002.eps Type the following except block, which catches the TypeError exception. Press Ent at the end of each line, and then press Ent again to end the block.

except TypeError:

print("A TypeError exception has occurred.")

dgc.eps Python displays the resulting message:

A TypeError exception has occurred.

Add an else Block or a finally Block

You can add an else block to a try… except block to execute statements when no exception has occurred. You can also add a finally block containing statements that you want to execute when the try… except block has finished running, whether or not any exception arises. This section shows a finally block that displays information, but the block can be useful for performing cleanup operations, such as closing files.

Add an else Block or a finally Block

Snapshot of add an else block.

Snapshot of add an else block.

001.eps Open a terminal window and launch Python.

002.eps Type the following try block, which creates the variable n and assigns 51 to it; creates the variable d and assigns the user’s input divisor, cast to an integer; and creates the variable msg and assigns a message to it.

try:

n = 51

d = int(input("Enter the integer divisor: "))

msg = str(n) + " divided by " + str(d) + " equals " + str(n/d)

003.eps Type the following except block to handle a potential ZeroDivisionError exception:

except ZeroDivisionError:

msg = "You cannot divide by zero."

Snapshot of add a finally block.

004.eps Type the following finally block, which displays the contents of msg:

finally:

print(msg)

005.eps Press Ent again to end the block.

006.eps Type an integer at the prompt.

dgb.eps The result appears.

Create Nested try… except Blocks

Python enables you to nest try… except blocks inside other try… except blocks. Nesting blocks enables you to perform more complex error handling.

If an exception is raised in the outer try… except block, the outer block handles the exception. If the inner try… except block raises an exception, the inner block handles the exception; if it fails to do so — for example, because it has no unqualified except statement — the outer block takes over responsibility for handling the exception.

Create Nested try… except Blocks

Snapshot of create nested try except blocks.

001.eps Open Visual Studio Code and create a new Python script.

002.eps Type the following statement, which creates a variable called adrFile and assigns to it the file addresses.csv. Press Ent.

adrFile = "addresses.csv"

003.eps Type the following statement, which creates a variable named addresses and assigns to it an empty list. Press Ent.

adrs = []

004.eps Type the following try block, which uses the open() function to open addressFile in Read Mode. Press Ent.

try:

f = open("adrFile", "r")

Snapshot of the same level of indentation.

005.eps At the same level of indentation, type the nested try block, which uses two for loops to iterate through the lines in f, split the addresses at the commas, and assign the resulting fields to the adrs list. Press Ent at the end of each line.

try:

for line in f.readlines():

currAdr=[]

for field in line.strip(' ').split(','):

currAdr.append(field)

adrs.append(currAdr)

006.eps Indented to the level of the inner try block, type the inner except block, which uses the print() function to display an error message. Press Ent at the end of each line.

except:

print("An error occurred in the inner try… except block.")

Snapshot of press backspace twice to remove the indent.

007.eps Press Bksp twice to remove the indent, and then type the following except block, which runs if the FileNotFoundError occurs. Press Ent at the end of each line.

except FileNotFoundError:

print(f"The file '{adrFile}' was not found.")

008.eps Press Bksp to remove the indent again, and then type the following unqualified except block, pressing Ent at the end of each line.

except:

print("An error occurred in the outer try… except block.")

Snapshot of the error message appears.

009.eps Press Bksp to remove the indent once more, and then type the following else block, which closes f and displays the addresses. Press Ent at the end of each line.

else:

f.close()

print(adrs)

010.eps Click Run Python File in Terminal (9781119860259-ma040).

The Terminal pane appears.

A FileNotFoundError occurs, because addresses.csv does not exist.

The except FileNotFoundError: block catches the exception.

dga.eps The error message appears.

011.eps Create a file named addresses.csv containing address information in the folder Python is using. Put each address on one line, with commas separating the fields.

012.eps Click Run Python File in Terminal (9781119860259-ma040).

dgb.eps The address information appears.

Create Custom Exceptions

As you have seen earlier in this chapter, Python includes a wide range of built-in exceptions. But Python also lets you create your own custom exceptions, which enables you to track exactly what is going wrong in your code.

To create custom exceptions, you create a class based on Python’s base class of exceptions. You can then use a raise statement to raise instances of the exception, assigning a custom error message to make clear the problem to the user. See Chapter 12, “Working with Classes,” for more information on classes.

Create Custom Exceptions

Snapshot of create custom exceptions.

001.eps Open Visual Studio Code and create a new Python script.

002.eps Type the following class header, which creates a class named InvalidTitle based on the Exception object.

class InvalidTitle(Exception):

003.eps Type the pass keyword as the only statement for the class, allowing the code to run without taking any action. Press Ent twice, creating a blank line.

pass

004.eps Press Bksp to delete the indent, and then type the start of a try block. Press Ent.

try:

“Snapshot of the following statement, which creates a variable named title.”

005.eps Type the following statement, which creates a variable named title and assigns to it the result of the input() function prompting the user to enter the title. Press Ent.

title = input("Type the title: ")

006.eps Type the following if block, which uses the isnumeric() method to check whether title is entirely numeric and, if so, raises an InvalidTitle instance with a custom error message. Press Ent at the end of each line.

if title.isnumeric():

raise InvalidTitle("The title is entirely numeric.")

Snapshot of remove one step of indentation.

007.eps Press Bksp to remove one step of indentation, and then type the following two elif blocks, which use the len() function to check the length of title and raise InvalidTitle instances if it is too short or too long:

elif len(title) < 5:

raise InvalidTitle("The title is too short.")

elif len(title) > 50:

raise InvalidTitle("The title is too long.")

008.eps Press Bksp once, and then type the following two elif blocks, which raise InvalidTitle instances for all uppercase and all lowercase:

elif title.isupper():

raise InvalidTitle("The title is all uppercase.")

elif title.islower():

raise InvalidTitle("The title is all lowercase.")

Snapshot of press backspace twice to remove the indentation.

009.eps Press Bksp twice to remove the indentation, and then type the following except statement, which casts an InvalidTitle exception to IT and prints that object:

except InvalidTitle as IT:

print(IT)

010.eps Press Bksp once to remove the indent, and then type the following if block, which displays title if no exception has been raised:

else:

print(title)

011.eps Click Run Python File in Terminal (9781119860259-ma040).

The Terminal pane appears.

012.eps When prompted, type a title.

dga.eps If the title provokes an exception, the relevant message appears.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.82.83