What is an exception?
An exception is an event that occurs during program execution and affects the normal execution of the program. Typically, an exception occurs when Python is unable to process a program properly. Exceptions are Python objects that represent an error. When an exception occurs in a Python script we need to catch it and handle it, otherwise the program will terminate execution.
When an uncaught exception occurs, Python will end the program and print a stack trace message, along with the exception name and additional information. The details are as follows.
Broadly speaking, errors are classified as errors and exceptions
- Errors usually refer to syntax errors, which can be avoided artificially
- Exceptions are problems that occur when the syntax is logically correct
The main purposes of catching and handling exceptions in Python are.
- Error handling: In the event of a runtime error, the application may terminate unconditionally. Using exception handling, we can handle failure cases and avoid program termination.
- Code separation: Error handling helps us to separate the code required for error handling from the main logic. The code associated with the error can be placed in an “except” block, which isolates it from the regular code containing the application logic.
- Error differentiation: helps us isolate the different types of errors encountered during execution. We can have multiple “except” blocks, each dealing with a specific type of error.
- Event notification: Exceptions can also be used as signals for certain conditions, without the need to pass result flags or test them explicitly in the program.
- Special case handling: Sometimes there are situations that rarely occur and it is better to change the corresponding handling code to exception handling.
- Special control flow: Exceptions are a high level “goto” that can be used as a basis for implementing special control flow. Such as reverse tracing, etc.
Python comes with a very powerful exception handling mechanism, providing many built-in exception classes that provide accurate feedback to the user. Python automatically puts all exception names in a built-in namespace, so programs don’t have to import the exceptions module to use exceptions.
Python’s built-in exception class inheritance hierarchy is as follows.
Exception catching and handling
We can’t guarantee that the programs we write will always run correctly, and the purpose of exception catching and handling is to ensure that the worst-case problems the program gets are managed properly.
In Python, exceptions are caught and handled with try except statement blocks, the basic syntactic structure of which is shown below.
The way try works is that when you start a try statement, python marks it in the context of the current program so that you can return to it when an exception occurs, the try clause is executed first, and what happens next depends on whether an exception occurs during execution.
If an exception occurs while the statement after try is executing, Python jumps back to try and executes the first exception clause that matches the exception, the exception is handled, and control flows through the entire try statement (unless a new exception is raised while the exception is being handled). If an exception occurs in the statement after try and there is no matching except clause, the exception is passed to the upper level of try, or to the top level of the program (which will end the program and print the default error message). If no exception occurs during the execution of the try clause, Python will execute the statement after the else statement (if there is an else), and then control flows through the entire try statement.
The Exception class is the parent of all Python exception classes, so except Exception will be able to catch any exception; in other words, it is the catch-all exception handling syntax. There is one kind of error that there is no way to catch: indentation errors.
raise: manually raise an exception
Sometimes an exception can be used as a flag for code to run, and by proactively triggering an exception you can change the course of the code, thus improving code robustness.
The active trigger exception requires the raise keyword, which has the following syntax structure.
The statement Exception is the type of the exception (e.g., ValueError) The parameter is an exception parameter value. This parameter is optional, and if not provided, the exception parameter is “None”. The last parameter is optional (rarely used in practice) and, if present, is a trace exception object.
You can have your own exceptions by creating a new exception class. Exception classes inherit from the Exception class, either directly, or indirectly, e.g.
Assertion: assert condition
Python assert is used to determine an expression and trigger an exception if the condition of the expression is false. Assertions can return an error directly if the condition is not met, without having to wait for the program to run and then crash. For example, if our code can only run on Linux, we can first determine if the current system meets the condition.
The syntax format is as follows.
assert looks good, however it is not pleasant to use. For example, someone tells you that the program is wrong, but doesn’t tell you what’s wrong. Many times such assert is better than not writing it at all. A common solution is to use a testing framework or other packages instead: py.test, unittest, ptest, assertpy…
traceback Get detailed exception information
The output of try…except… only lets you know that the error was reported, but not in which file, function, or line. Using the traceback module, you can get a very clear picture of where the error is.
Python programs get their traceback information from an object called the traceback object, which is usually obtained through the function sys.exc_info().
As we can see from the above example, sys.exc_info() gets the information about the currently handled exception and returns a tuple, the first data of the tuple is the type of the exception, the second return value is the value of the exception, and the third is the traceback object.
With the traceback object we can use the traceback module to print and format the information about the traceback.