Article directory
foreword
Past review:
- Python Series Tutorial – Introduction to Python3 (1)
- Python Series Tutorials – Python3 Environment Construction (2)
- Python Series Tutorial – Python3 VScode (3)
- Python Series Tutorials – Basic Grammar of Python3 (4)
- Python Series Tutorial – Python3 Basic Data Types (5)
- Python Series Tutorials--Python3 Data Type Conversion (6)
- Python Series Tutorials--Python3 Derivation (7)
- Python Series Tutorials--Python3 Interpreter and Annotations (8)
- Python series of tutorials--Python3 what is an operator (9)
- Python Series Tutorials--Python3 Numbers (Number) (10)
- Python Series Tutorials--Python3 Strings (11)
- Python Series Tutorials--Python3 List (12)
- Python Series Tutorials--Python3 Tuples (13)
- Python Series Tutorials--Python3 Dictionary (14)
- Python Series Tutorials--Python3 Collection (15)
- Python Series Tutorials--Python3 Conditional Control (16)
- Python Series Tutorial--Python3 Loop Statement (17)
- Python Series Tutorials--Python3 Programming Step One (18)
- Python Series Tutorials--Python3 Derivation (19)
- Python Series Tutorials--Python3 Iterators and Generators (20)
- Python Series Tutorials--Python3 Functions (21)
- Python Series Tutorials--Python3 Data Structure (22)
- Python Series Tutorials--Python3 Module (23)
- Python Series Tutorials--Python3 Input and Output (24)
- Python series of tutorials--Python3 File (file) method (25)
- Python Series Tutorials--Python3 OS File/Directory Method (26)
As a Python beginner, when you first learn Python programming, you often see some error messages, which we did not mention before, and we will introduce them in this chapter.
There are two types of errors in Python that are easily recognizable: syntax errors and exceptions.
Python assert (assertion) is used to judge an expression and trigger an exception when the expression condition is false.
Grammatical 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() is checked for an error because it is missing a colon : in front of it.
The parser points out the wrong line and marks a small arrow at the location of the first error found.
abnormal
Even if the syntax of a Python program is correct, errors may occur when running it. Errors detected at runtime are called exceptions.
Most exceptions will not be handled by the program, and are displayed here in the form of error messages:
example
>>> 10 * (1/0) # 0 不能作为除数,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3 # spam 未定义,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2 # int 不能与 str 相加,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
Exceptions occur in different types, which are all printed as part of the message: the types in the example are ZeroDivisionError, NameError and TypeError.
The front part of the error message shows the context where the exception occurred, and the specific information is displayed in the form of a call stack.
exception handling
try/except
Exception capture can use try/except statement.
In the following example, let the user enter a legal integer, but allow the user to interrupt the program (using Control-C or the method provided by the operating system). User interrupted information will raise a KeyboardInterrupt exception.
while True:
try:
x = int(input("请输入一个数字: "))
break
except ValueError:
print("您输入的不是数字,请再次尝试输入!")
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, ignore the except clause, and end after the try clause is executed.
-
If an exception occurs during the execution of the try clause, the rest of the try clause is ignored. If the exception type matches the name after except, then the corresponding except clause will be executed.
-
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's handlers.
An except clause can handle multiple exceptions at the same time, and these exceptions will be placed in a parenthesis as a tuple, for example:
except (RuntimeError, TypeError, NameError):
pass
The last except clause can omit 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/except…else
The try/except statement also has an optional else clause. If this clause is used, it must be placed after all except clauses.
The else clause will be executed if no exception occurs in the try clause.
The following example judges whether the file can be opened in the try statement. If there is no exception when opening the file, execute the statement in the else part to read the file content:
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 the statements in the try clause, so as to avoid some unexpected exceptions that cannot be 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 indirectly called functions). 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
try-finally statement
The try-finally statement executes the final code whether or not an exception occurs.
The finally statement in the following example is executed regardless of whether an exception occurs:
example
try:
demo()
except AssertionError as error:
print(error)
else:
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
finally:
print('这句话,无论异常是否发生都会执行。')
Throw an exception
Python uses the raise statement to raise a specified exception.
The syntax format of raise is as follows:
raise [Exception [, args [, traceback]]]
The following example triggers an exception if x is greater than 5:
x = 10
if x > 5:
raise Exception('x 不能大于 5。x 的值为: {}'.format(x))
Executing the above code will trigger an exception:
Traceback (most recent call last):
File "test.py", line 3, in <module>
raise Exception('x 不能大于 5。x 的值为: {}'.format(x))
Exception: x 不能大于 5。x 的值为: 10
The only parameter to raise specifies the exception to be thrown. It must be an instance of an exception 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 raise 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 exception
You can have your own exceptions by creating a new exception class. The exception class inherits from the Exception class and can be inherited 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!'
在这个例子中,类 Exception 默认的 __init__() 被覆盖。
当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类:
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 the standard exception names.
Define cleanup behavior
The try statement has another optional clause, which defines the cleanup behavior to be performed no matter what the circumstances. For example:
>>> try:
... raise KeyboardInterrupt
... finally:
... print('Goodbye, world!')
...
Goodbye, world!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
In the above example, regardless of whether there is an exception in the try clause, the finally clause will be executed.
If an exception is thrown in the try clause (or in the except and else clauses), and there is no except to catch it, then the exception will be thrown after the finally clause is executed.
Here's a more complex example (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 objects define a standard cleanup behavior that will be performed once it is no longer needed, regardless of whether the system successfully uses it.
The following example shows an attempt to open a file and 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 complete, the file remains open and is not closed.
The keyword with statement can ensure that objects such as files will correctly execute his cleanup method after use:
with open("myfile.txt") as f:
for line in f:
print(line, end="")
After the above code is executed, even if something goes wrong during processing, the file f will always be closed.