There are often mistakes in the program , Common errors include but are not limited to :
Grammar mistakes :“SyntaxError:invalid syntax”
abnormal :xxError, Such as NameError、TypeError、IndentationError、ModuleNotFoundError etc.
Grammar mistakes , It can be found before running . If you use PyCharm There will be a red wavy line to remind you , Please check spell 、 Indent 、 Symbol And so on .(SyntaxError It is also an anomaly , But because it is special , It can be checked out before running , So alone .)
abnormal There are a lot of things , Specific analysis is required according to the error content . Let's take a look at what exceptions are and how to handle them .
Unexpected errors often occur during program execution , That is to say abnormal .
These errors are not necessarily programming problems , It may also be the user's illegal input 、 Network problems, etc. lead to program errors .
For example, a calculator program , User input 1/0 When ,0 It makes no sense to be a denominator . Therefore, the program cannot execute normally , Trigger errors .
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
In actual procedure , We may encounter various anomalies .
Built-in exception — Python 3.10.4 file Most of the possible exceptions are provided in , Such as IO abnormal , Iteration exception 、 Coding error, exception, etc .
BaseException
Is the base class for all exceptions , It can be used to catch all exceptions .
But more often Exception
.Exception
It is the base class for all built-in non system exit class exceptions . All user-defined exceptions should also derive from this class .
It's usually used try-except Statement to prevent errors in advance .
Grammar format :
try:
...
Do something that may go wrong
except Exception types :
...
Explain and handle the error
for example , We wrote a read from user input a,b, And calculate a/b The program .
The user may enter a non digital content , trigger ValueError
, It's also possible to enter 0 As divisor , trigger ZeroDivisionError
.
So we put the statements that may go wrong in try
Inside , And use except
Catch errors .
try:
a = int(input('a= '))
b = int(input('b= '))
print('a/b= ',a/b)
except (ValueError,ZeroDivisionError):
print(" Invalid input , Please try again ")
try
The statement works as follows :
First , perform try Clause .
If no exception is triggered , Then skip except Clause ,try
Statement execution finished .
If in execution try
Exception in clause , Then skip the rest of the clause . If the type of exception is the same as except
Exception specified after keyword Match , Will perform except Clause , Then jump to try/except Continue execution after the code block . If an exception occurs with except Clause Exception specified in Mismatch , Then it will be passed to the external try
In the sentence ; If no handler is found , Then it is a Unhandled exception And the execution will terminate and output an error message .
except Clause You can specify multiple exceptions with parenthesized tuples , for example :
except (RuntimeError, TypeError, NameError):
pass
try
It can be followed by multiple except
, To catch a variety of exceptions . If the exception is detected by the previous except Captured , Then the back except Will not proceed with :
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print(err.args)
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except BaseException as err:
print(f"Unexpected {err=}, {type(err)=}")
raise
except Clause You can use... After the exception name as
Specify a variable . This variable will bind to an exception instance and store the parameters in instance.args
in . print(err) Will call the exception class __str__()
Method , Get the string representing the exception .
try
… except
The statement has an optional else Clause , If this clause exists , It must be placed in all except Clause after . else Will be in try Clause Execute when no exception is thrown . for example :
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except OSError:
print('cannot open', arg)
else: # If there is no abnormality , Then read the file
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
try
Statement also has an optional clause finally
, Used to define the cleanup operations that must be performed in all cases . for example :
try:
raise KeyboardInterrupt
finally:
print('Goodbye, world!')
Regardless of try
Whether the statement triggers an exception , It will be carried out finally
Clause . In a real application ,finally
Clause for releasing external resources ( For example, file or network connection ) Very useful .
with The sentence is try-finally A simplified way of writing , It is equivalent to hiding a finally To clean up resources :
with open("myfile.txt") as f:
for line in f:
print(line, end="")
try-finally Special circumstances :
The following contents introduce several complex triggering exception scenarios :
If you execute try
An exception was triggered during the clause , Then a except
Clause should handle the exception . If the exception does not except
Clause processing , stay finally
Clause will be triggered again after execution .
except
or else
An exception is also triggered during clause execution . Again , The exception will be in finally
Clause is triggered again after execution .
If finally
Clause contains break
、continue
or return
Such statements , Exceptions will not be re thrown .
If you execute try
Statement encountered break
,、continue
or return
sentence , be finally
Clause is executing break
、continue
or return
Execute before statement .
If finally
Clause contains return
sentence , The return value comes from finally
One of the clauses return
The return value of the statement , Not from try
Clause return
The return value of the statement .
raise
Statement can throw the specified exception :
raise abnormal
raise NameError('HiThere')
If you don't want to handle after catching an exception , You can use a single raise
Rethrow exception :
try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
raise
raise
Support optional from
Clause , Used to enable chained exceptions .
Such as :raise RuntimeError from exc
Conversion exception , It works . for example :
def func():
raise ConnectionError
try:
func()
except ConnectionError as exc:
raise RuntimeError('Failed to open database') from exc
The exception chain will be in except
or finally
Automatically generated when an exception is thrown inside a clause . This can be done by using from None
This way of writing to disable :
try:
open('database.sqlite')
except OSError:
raise RuntimeError from None
Users can customize inheritance Exception
Class to implement its own exception . Most exceptions are named after “Error” ending , Similar to the naming of standard exceptions .( The first 9 The chapter class describes how to define classes )
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
try:
raise MyError(42)
except MyError as e:
print(e)