raise(抛出异常)
当 Python 试图执行无效代码时,就会抛出异常,
以下是一个用 raise
来抛出一个异常的语句;
raise Exception('This is the error message.') # 抛出一个异常
运行结果:
Traceback (most recent call last):
File"C:/Users/007766/.PyCharmCE2018.3/config/scratches/debug_draft.py", line 1, in
raise Exception(‘This is the error message.’)
Exception: This is the error message. # 程序崩溃
try - except
希望程序发生异常时得到相应的异常信息,而不是让程序崩溃,可用 try - except
语句处理程序异常;
在 try
语句块中,发生的所有错误都会被捕捉,然后执行 except
对应的语句,然后跳出try - except
语句,再跳出当前函数;
try
语句的工作原理
- 首先,执行
try
子句 (try
和except
关键字之间的语句)。 - 如果没有异常发生,则跳过 except 子句并完成 try - except 语句的执行。
- 如果在执行
try
子句时发生了异常,则跳过该子句中剩下的部分。然后,如果异常的类型和except
关键字后面的异常匹配,则执行except
子句 ,然后继续执行try
语句之后的代码。 - 如果发生的异常和
except
子句中指定的异常不匹配,则将其传递到外部的try
语句中;如果没有找到处理程序,则它是一个未处理异常,执行将停止并显示如上所示的消息。
def spam(divideBy): # 在函数中添加异常处理语句
try:
return 42 / divideBy
except ZeroDivisionError:
print('Error: Invalid argument.')
print(spam(0))
运行结果:
21.0
Error : Invalid argument. # 抛出异常,异常于程序中设定的 ZeroDivisionError 异常不匹配,但程序并没崩溃
None
结合 raise
的 try - except
语句
def boxPrint(symbol,width,height):
if len(symbol) != 1:
raise Exception('Symbol must be a single character string.') # 抛出异常字符串,跳出函数
if width <= 2:
raise Exception('Width must be greater than 2.')
if height <= 2:
raise Exception('Height must be greater than 2.')
print(symbol * width)
for i in range(height - 2):
print(symbol + (' ' * (width - 2)) + symbol)
print(symbol * width)
for sym,w,h in (('*',4,4),('0',20,5),('x',1,33),('zz',3,3)):
try:
boxPrint(sym,w,h)
except Exception as err: # 若有异常抛出,则执行except,传入err字符串
print('An exception happened: ' + str(err))
运行结果:
****
* *
* *
****
00000000000000000000
0 0
0 0
0 0
00000000000000000000
An exception happened: Width must be greater than 2.
An exception happened: Symbol must be a single character string.
异常的反向跟踪
如果 Python 遇到错误,它就会生成一些错误信息,并调用栈的方式逐次显示出来,称为“反向跟踪”
;
只要抛出的异常没被处理,Python 就会显示反向跟踪,让程序崩溃;
def spam(divideBy):
return 42 / divideBy
print(spam(2))
print(spam(0))
运行结果:
Traceback (most recent call last):
21.0
File
“C:/Users/007766/.PyCharmCE2018.3/config/scratches/debug_draft.py”,
line 24, inprint(spam(0)) # ② 该错误在24行中被调用
File
“C:/Users/007766/.PyCharmCE2018.3/config/scratches/debug_draft.py”,
line 22, in spamreturn 42 / divideBy # ① 通过反向跟踪,发现异常发生在22行
ZeroDivisionError: division by zero
traceback
模块
可通过traceback.format_exc()
得到异常的字符串形式;
import traceback,os
def spam(divideBy):
try:
return 42 / divideBy
except :
filePath = os.getcwd()
errorFile = open(filePath + '\\errorInfo' + '\\errorInfo.txt','w') # 创建一个文件保存报错信息
errorFile.write(traceback.format_exc())
errorFile.close()
print('The traceback info was written to errorInfo.txt,(' + filePath + '\\errorInfo)\n' )
print(spam(0))
断言
利用断言,可检查判断语句,若检查失败,就抛出异常,让系统崩溃;
podBayDoorStatus = 'open'
assert podBayDoorStatus == 'open','The pod bay dors need to be "open".'
podBayDoorStatus = 'I\'m sorry ,Dave. I\'m afraid I can\'t do that.'
assert podBayDoorStatus == 'open','The pod bay dors need to be "open".' # 当断言检查失败,显示后者字符串
运行结果:
Traceback (most recent call last):
File
“C:/Users/007766/.PyCharmCE2018.3/config/scratches/debug_draft.py”,
line 53, inassert podBayDoorStatus == 'open','The pod bay dors need to be "open".' # 当断言检查失败,显示后者字符串
AssertionError: The pod bay dors need to be “open”.
断言
与 try - except
语句的区别
断言
与try - except
语句不同,若断言失败,程序就应该在此崩溃,从而提高调试效率;断言
是针对程序员的错误,而不是用户的错误,对于程序使用的错误,应用 try - except
语句处理异常;