Python3 errors and exceptions
As a Python beginner, when you first learn Python programming, you will often see some error messages. We have not mentioned them before, but we will introduce them specifically in this chapter.
There are two types of errors in Python that are easy to identify: syntax errors and exceptions.
Grammar errors
Python grammatical errors, or parsing errors, are often encountered by beginners, as shown in the following example
>>> while True print('Hello world') File "<stdin>", line 1, in ? while True print('Hello world') ^ SyntaxError: invalid syntax
In this example, the function print() An error was detected because a colon (:) was missing in front of it.
The parser points out the line in error and marks the first error found with a small arrow.
Exception
Even if the syntax of the Python program is correct, errors may occur when running it. Errors detected during runtime are called exceptions.
Most exceptions will not be handled by the program, and are displayed here in the form of error messages:
>>> 10 * (1/0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: division by zero >>> 4 + spam*3 Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'spam' is not defined >>> '2' + 2 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: Can't convert 'int' object to str implicitly
Exceptions appear in different types, and these types are printed as part of the information. : The types in the example are ZeroDivisionError, NameError and TypeError.
The front part of the error message shows the context in which the exception occurred, and displays specific information in the form of a call stack.
Exception handling
In the following example, the user is allowed to enter a legal integer, but the user is allowed to interrupt the program (using Control-C or the method provided by the operating system). User-interrupted messages raise a KeyboardInterrupt exception.
>>> while True: try: x = int(input("Please enter a number: ")) break except ValueError: print("Oops! That was no valid number. Try again ")
The try statement works as follows;
First, the try clause (the statement between the keyword try and the keyword except) is executed
If no exception occurs, the except clause is ignored and the try clause ends after execution.
If an exception occurs during the execution of the try clause, the remainder of the try clause will be ignored. If the exception type matches the name after except, the corresponding except clause will be executed. Finally execute the code after the try statement.
If an exception does not match any except, then the exception will be passed to the upper try.
A try statement may contain multiple except clauses to handle different specific exceptions. At most one branch will be executed.
The handler will only handle exceptions in the corresponding try clause, not exceptions in other try handlers.
An except clause can handle multiple exceptions at the same time. These exceptions will be placed in parentheses to become a tuple, for example:
except (RuntimeError, TypeError, NameError): pass
The last except clause can ignore the name of the exception. , it will be used as a wildcard. You can use this method to print an error message and then throw the exception again.
import sys try: f = open('myfile.txt') s = f.readline() i = int(s.strip()) except OSError as err: print("OS error: {0}".format(err)) except ValueError: print("Could not convert data to an integer.") except: print("Unexpected error:", sys.exc_info()[0]) raise
try The except statement also has an optional else clause. If this clause is used, it must be placed after all except clauses. This clause will be executed when no exception occurs in the try clause. For example:
for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print('cannot open', arg) else: print(arg, 'has', len(f.readlines()), 'lines') f.close()
Using the else clause is better than putting all statements in the try clause, so as to avoid some unexpected exceptions that are not caught by except.
Exception handling not only handles exceptions that occur directly in the try clause, but also handles exceptions thrown in functions called in the clause (even functions called indirectly). For example:
>>> def this_fails(): x = 1/0 >>> try: this_fails() except ZeroDivisionError as err: print('Handling run-time error:', err) Handling run-time error: int division or modulo by zero
Throw an exception
Python uses the raise statement to throw a specified exception. For example:
>>> raise NameError('HiThere') Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: HiThere
raise The only parameter specifies the exception to be thrown. It must be an exception instance or an exception class (that is, a subclass of Exception).
If you just want to know if this threw an exception and don't want to handle it, then a simple raise statement can throw it again.
>>> try: raise NameError('HiThere') except NameError: print('An exception flew by!') raise An exception flew by! Traceback (most recent call last): File "<stdin>", line 2, in ? NameError: HiThere
User-defined exceptions
You can have your own exceptions by creating a new exception class. Exceptions should inherit from the Exception class, either directly or indirectly, for example:
>>> class MyError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) >>> try: raise MyError(2*2) except MyError as e: print('My exception occurred, value:', e.value) My exception occurred, value: 4 >>> raise MyError('oops!') Traceback (most recent call last): File "<stdin>", line 1, in ? __main__.MyError: 'oops!'
In this example, the default __init__() of class Exception is overridden.
<pException classes can do anything like other classes, but they are usually simpler, providing only some error-related properties and allowing the code that handles the exception to easily obtain this information. < p="">When creating a module that may throw multiple different exceptions, a common approach is to create a base exception class for the package, and then provide different errors based on this base class. Create different subclasses:
class Error(Exception): """Base class for exceptions in this module.""" pass class InputError(Error): """Exception raised for errors in the input. Attributes: expression -- input expression in which the error occurred message -- explanation of the error """ def __init__(self, expression, message): self.expression = expression self.message = message class TransitionError(Error): """Raised when an operation attempts a state transition that's not allowed. Attributes: previous -- state at beginning of transition next -- attempted new state message -- explanation of why the specific transition is not allowed """ def __init__(self, previous, next, message): self.previous = previous self.next = next self.message = message
Most exception names end with "Error", just like standard exception naming.
Define cleanup behavior
The try statement has another optional clause, which defines the cleanup behavior that will be executed under any circumstances. For example:
>>> try: raise KeyboardInterrupt finally: print('Goodbye, world!') Goodbye, world! KeyboardInterrupt
In the above example, the finally clause will be executed regardless of whether an exception occurs in the try clause.
If an exception is thrown in the try clause (or in the except and else clauses) and there is no except to intercept it, then the exception will occur again after the finally clause is executed. was thrown.
The following is a more complex example (containing except and finally clauses in the same try statement):
>>> def divide(x, y): try: result = x / y except ZeroDivisionError: print("division by zero!") else: print("result is", result) finally: print("executing finally clause") >>> divide(2, 1) result is 2.0 executing finally clause >>> divide(2, 0) division by zero! executing finally clause >>> divide("2", "1") executing finally clause Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 3, in divide TypeError: unsupported operand type(s) for /: 'str' and 'str'
Predefined cleanup behavior
Some The object defines standard cleanup behavior. Regardless of whether the system successfully uses it, once it is no longer needed, this standard cleanup behavior will be executed.
This example shows trying to open a file and then print the contents to the screen:
for line in open("myfile.txt"): print(line, end="")
The problem with the above code is that when execution is completed, the file will remain open. , and has not been closed.
The keyword with statement can ensure that objects such as files will correctly execute their cleaning methods after use:
with open("myfile.txt") as f: for line in f: print(line, end="")
After the above code is executed, even if Something went wrong during processing and file f was always closed.