Книга: Practical Programming, Fourth Edition
Назад: Core Idioms
Дальше: Common Built-in Exceptions

Accessing Exception Details

A traceback, also known as a stack trace, is a report generated by the Python interpreter when an unhandled exception occurs in a program. From a debugging perspective, a traceback is a treasure trove of information: it provides a detailed account of the sequence of function calls that led to the error, helping you pinpoint its source.

In the following example, we define a function average that computes the average of a numerical sequence seq, and a helper function divide that, for no particular reason, divides a by b. We test average on an empty sequence, which predictably raises a ZeroDivisionError:

 >>>​​ ​​from​​ ​​typing​​ ​​import​​ ​​Sequence
 >>>​​ ​​def​​ ​​divide(a:​​ ​​float,​​ ​​b:​​ ​​float)​​ ​​->​​ ​​float:
 ...​​ ​​"""Return the ratio of the numbers `a` and `b`. """
 ...​​ ​​return​​ ​​a​​ ​​/​​ ​​b
 ...
 >>>​​ ​​def​​ ​​average(seq:​​ ​​Sequence[float])​​ ​​->​​ ​​float:
 ...​​ ​​"""Return the average of the items in the sequence. """
 ...​​ ​​return​​ ​​divide(sum(seq),​​ ​​len(seq))
 ...
 >>>​​ ​​avg​​ ​​=​​ ​​average([])
 Traceback (most recent call last):
  File "<python-input-2>", line 1, in <module>
  average([])
  ~~~~~~~^^^^
  File "<python-input-1>", line 2, in average
  return divide(sum(seq), len(seq))
  File "<python-input-0>", line 2, in divide
  return a / b
  ~~^~~
 ZeroDivisionError: division by zero

Unlike the previous examples, the exception here is not raised by the call to average, but by the deeper call to divide, as clearly indicated by the traceback.

For each function call, the traceback shows the file name where the function is defined, the function name, and the code snippet that caused the exception (with the line number). Since this code was entered interactively, the file names (<python-input-N>) are phony, and the top-level function <module> refers to the code executed at the command line. Here’s the previous traceback, parsed out:

File

Line

Function

Code Snippet

<python-input-2>

1

<module>

average([])

<python-input-1>

2

average

return divide(sum(seq), len(seq))

<python-input-0>

2

divide

return a / b

Given the traceback, you can follow the history of the program’s execution from the line where the top-level function was called back through the chain of function calls to the point where the exception was raised (hence the name traceback).

The try/except statement can also provide an exception object, which you can capture by using the as keyword in the except block. This object contains useful information about the error, such as its type and any additional arguments that accompany it. These arguments are stored in the args attribute, a tuple that you can inspect for more details. In this example, we use the most general exception type, Exception, but more specific types (like ZeroDivisionError) can be used for finer-grained handling.

 >>>​​ ​​try:
 ...​​ ​​avg​​ ​​=​​ ​​average([])
 ...​​ ​​except​​ ​​Exception​​ ​​as​​ ​​eo:
 ...​​ ​​for​​ ​​arg​​ ​​in​​ ​​eo.args:
 ...​​ ​​print(arg)
 ...​​ ​​print(type(eo))
 ...
 division by zero
 <class 'ZeroDivisionError'>

You will learn more about exception arguments in .

Except That eo Is Local

icon indicating an aside

The scope of the exception object (eo in the ) is limited to the except block. If you need to use it elsewhere in your code (for example, to log the error or pass it to another function), you must assign it to a variable with a broader scope before the block ends.

Назад: Core Idioms
Дальше: Common Built-in Exceptions