Python程序设计基础教程课件 第13章 异常处理_第1页
Python程序设计基础教程课件 第13章 异常处理_第2页
Python程序设计基础教程课件 第13章 异常处理_第3页
Python程序设计基础教程课件 第13章 异常处理_第4页
Python程序设计基础教程课件 第13章 异常处理_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第13章

异常处理异常(exception)简单地说,异常是指程序运行时引发的错误。引发错误的原因有很多,例如除零、下标越界、文件不存在、网络异常、类型错误、名字错误、字典键错误、磁盘空间不足等等。如果这些错误得不到正确的处理将会导致程序终止运行,而合理地使用异常处理结果可以使得程序更加健壮,具有更强的容错性,不会因为用户不小心的错误输入或其他运行时原因而造成程序终止。也可以使用异常处理为用户提供更加友好的提示。程序出现异常或错误之后是否能够调试程序并快速定位和解决存在的问题也是程序员综合水平和能力的重要体现方式之一。13.1异常词法分析语法分析字节码运行类型检查内存管理可能的错误语法错误对齐不正确可能的错误变量不存在下标不存在文件不存在…可能的错误类型不正确OOM:内存溢出…什么是异常语法错误和逻辑错误不属于异常,但有些语法错误往往会导致异常,例如由于大小写拼写错误而访问不存在的对象。当Python检测到一个错误时,解释器就会指出当前无法继续执行下去,这时候就出现了异常。异常是指因为程序出错而在正常控制流以外采取的行为。异常分两阶段:第一阶段是引发异常;第二阶段是检测并处理异常。不建议使用异常来代替常规的检查,如if...else判断。当程序出现错误,python会自动引发异常,也可以通过raise引发异常。13.2Python常见异常类下表列出了常用的异常类异常类的使用异常类有两种使用方式异常处理语句(13.3)

通过使用try…catch…else…finally的形式,控制异常发生以及处理的过程,从而增强程序的健壮性。引发异常(13.5)

在检测到函数参数或者程序状态处于非正常的情况下,可以通过raise语句,引发异常。13.3异常处理Python异常处理由try语句实现,语法形式如下上面是计算机中用于描述语言的语法,使用了特殊的符号try语句分为两类,分别是上面的try1和try2异常处理语句。try语句包括try子句、except子句、else子句和finally子句;这些子句具有不同的功能。try_stmt

::=

try1_stmt|try2_stmttry1_stmt

::=

"try"

":"suite

("except"

[expression["as"identifier]]

":"suite)+

["else"

":"suite]

["finally"

":"suite]try2_stmt

::=

"try"

":"suite

"finally"

":"suite语法符号的含义::=表示定义|表示或者[]表示可选()表示作为整体+表示重复≥1次suite

表示语句try子句try子句是必须的,其形式为其中的子句(suite)可以是任意的python语句,在子句的前面必须是try关键字且其后必须是冒号(:)。这些语句放置在try后加以保护。如果运行时语句没有出现异常,那么子句中的所有语句会依次运行,并且不启动异常处理流程;如果运行时语句出现了异常,那么异常点之后的所有try块的语句都不会执行;同时python解释器会生成一个异常对象,后续进入异常处理流程。"try"

":"suiteexcept子句except子句必须在try子句之后,其形式为except子句由一个以上(上面的+表示)的例外处理句柄构成。例外处理句柄由关键字except开头,包含可选的表达式或表达式as标识符两种形式。通常表达式由内置的异常类或用户自定义的异常类表示。在冒号(:)之后是处理句柄的语句(suite)。通常例外处理句柄有以下三种形式handler::="except"

[expression["as"identifier]]

":"

suite(handler)+except

NameError

ase:passexcept

NameError:passexcept:pass通配符except子句except子句的执行except子句处理规则1)如果try子句没有产生异常,则except子句不执行。如果后续有else子句,则转去执行else子句。2)如果try子句产生了异常,则python解释器将查找与当前异常对象匹配的异常处理句柄。匹配会从第一个异常处理句柄开始,直到找到匹配的异常处理句柄,或者直到except子句结束仍未找到匹配的异常处理句柄。带有表达式的异常处理句柄会被求值,若计算的结果与引发的异常”类型兼容”,则该异常处理句柄匹配该异常。类型兼容是指结果对象是该异常对象所属类或其基类;或者结果对象包含异常对象所属类或其基类的元组。没有表达式的异常处理句柄(通配符处理句柄),可以匹配任意的异常。因此这种异常处理句柄通常会放在except子句的结尾。找到匹配的异常处理句柄之后,python解释器会执行该句柄。不管有没有找到匹配的异常处理句柄,如果后续有finally子句,则转去执行finally子句。else子句else子句是可选的且只能有一个,其形式为else子句处理规则1)当try语句执行完且没有引发异常,并且try语句中并不包含break、continue或return语句时,else语句会被执行;否则,else语句将不会被执行。2)如果else语句中又引发了新的异常,这个异常不会被前面的try语句捕获!"else"

":"suitefinally子句finally子句是可选的且只能有一个,且必须放在try语句的最后,其形式为finally子句处理规则1)不管try子句有没有引发异常,finally子句一定会被执行。因此,通常会在finally子句中定义资源清理功能。2)无论try子句中是否包含return、break或continue语句,finally子句在离开时都会执行。3)在到达finally子句时,如果存在未被处理的异常对象(例如try语句引发了异常,但是没有找到匹配的异常处理句柄),该异常对象会被暂存。在finally子句的末尾会重新引发该暂存的异常;如果finally子句又引发了新异常,被暂存的异常会称为新异常的上下文;如果finally子句执行了return、break或continue语句,暂存的异常对象会被丢弃。"finally"

":"suite异常处理示例(1)例2

分析下面的输出结果bar函数中的try…finally形式是第2中形式的异常处理。try子句不会引发异常;finally子句和try子句中都包含return语句;函数的返回值由finally子句中的return语句决定。因此最后的返回值为“finally”。>>>defbar():...try:...return'try'...finally:...return'finally'

>>>print(bar)异常处理示例(2)例3

分析下面的输出结果foo函数中的try子句引发了ZeroDivisionError异常finally子句包含return语句,因此抑制了try子句中的异常;函数的返回值为2024;因此程序的输出为”2024”。>>>deffoo():...try:...1/0...finally:...return2024>>>foo()异常处理示例(3)例4分析下面的输出结果foobar函数中的try子句引发了ZeroDivisionError异常,通配符异常处理句柄匹配该异常,同时又引发了新异常ValueErrorfinally子句包含return语句,因此抑制了try子句中的异常;函数的返回值为2024;因此程序的输出为”2024”。>>>deffoobar():...try:...1/0...except:...raiseValueError...finally:...return2024>>>foobar()异常处理示例(4)例5

读模式访问文件try:f=open("data.txt",mode="rt")#1print(f.readlines())#2exceptFileNotFoundErroraserror:print(error.args[1])#3exceptOSErroraserror:print(error.args)#4finally:f.close()#5√√√文件存在且具有读访问权限文件不存在√√√×文件存在且没有读访问权限√√√×(13,'Permissiondenied')NameError:name'f'isnotdefinedNosuchfileordirectoryNameError:name'f'isnotdefined没有输出异常处理示例(5)例6读模式访问文件,忽略某些异常。try:

f=open("data.txt",mode="rt")#1print(f.readlines())#2f.close()except(FileNotFoundError,PermissionError):

pass

#3上面的代码在异常处理句柄中使用了pass语句;使用了元组匹配多种异常。这样使得最终这两种异常都会被忽略。13.5引发异常主动引发异常使用内置异常类;或使用自定义异常类。引发异常使用raise关键字,其语法形式如下expression:是一个异常类,或异常类的实例;another_expression:是另外一个异常类,或异常类的实例。上面的语法形式表示了三种形式的raise语句raise[expression

[fromanother_expression]]

raise

#1raiseexpression

#2raiseexpressionfrom

another_expression#31)不带参数引发异常不带参数引发异常,形式如下这种形式主要用于重新引发正在处理的异常:正在处理的异常通常称为活动异常。try子句中引发的异常,如果有匹配的异常处理句柄,在处理完毕之后,该异常对象会被销毁。某些情况下,需要保留该异常对象,此时可以使用不带参数引发异常。raise

#1importloggingtry:2024/0exceptExceptionaserror:logging.error(error)

raise例7在代码出现异常的情况下,记录异常的信息,且不影响该异常的正常处理。代码分析:在异常处理句柄中,使用Exception类捕获了多数异常;同时,使用raise语句重新引发已处理的异常。2)带表达式的引发异常带表达式的引发异常形式如下这种形式主要用于引发异常的一般形式;在处理异常过程中重新引发原有异常,或在程序的任意位置引发新异常;表达式必须是BaseException类或其子类的实例。raiseexpression#1例8根据要求引发新异常。代码分析:函数divide对参数a和b进行了检查;如果a和b的类型不是int类型,引发TypeError异常;如果b为0值,引发ValueError异常。defdivide(a,b):ifnot(type(a)==intandtype(b)==int):raiseTypeError("除数和被除数应该是整数")ifb==0:raiseValueError("被除数为0")returna//b2)带表达式的引发异常例9把例7的代码更改为raiseerror。代码分析:代码功能和例7是一样的。importloggingtry:2024/0exceptExceptionaserror:logging.error(error)

raise

error3)带from子句引发异常带from子句引发异常语法形式如下这种形式引发异常的作用包括:抑制链式异常或指明异常产生的原因。抑制异常:把例7的代码更改为raiseValueError("")fromNone。代码分析:代码功能和例7类似的;但是指明None,则实际上抑制了异常;避免了链式异常可能出现的大量信息。importloggingtry:2024/0exceptExceptionaserror:logging.error(error)

raiseValueError("")fromNoneraiseexpressionfromanother_expression#3自定义异常类下面的例子演示了自定义的异常类必须继承Exception类:所有异常类的基类;class

GradeValueError(Exception):

passdef

reckon_average_grade(grades):

total,count=

0,0

forgradeingrades:

ifgrade<

0

orgrade>

100:

raiseGradeValueError("分数须在[0,100]之间")

total,count=total+grade,count+1

return

round(total/count,2)>>>reckon_average_grade([98,87,110])Traceback(mostrecentcalllast):

File"<stdin>",line1,in<module>

File"<stdin>",line8,incalculate_average_gradeGradeValueError:分数须在[0,100]之间命名约定:自定义异常类使用大写的骆峰命名;如果是错误,则命名的最后部分附加单词Error;如果是警告,则命名的最后部分附加单词Warning。13.6异常处理方式处理异常的两种方式预防式策略防止错误或者异常的产生;通过条件语句来实现;没有异常处理机制的语言常用这种策略。处理式策略放任错误或异常的发生,然后使用异常处理机制;提供了异常处理机制的语言常用这种策略;python中没有没有引发异常时,异常处理的开销小,因此鼓励使用处理式策略。策略的比较例10编写函数char_frequency,对于给定的文本统计字符的出现频度。def

char_frequency_pre(text):

counter={}

forcharintext:

ifcharnot

incounter.keys():

counter[char]=

1

else:

counter[char]+=

1

returncounterdef

char_frequency_post(text):

counter={}

forcharintext:

try:

counter[char]+=

1

except

KeyError:

counter[char]=

1

returncounter预防式策略处理式策略处理时间短编码简单策略的比较例11编写函数convert_int(s),把字符串形式的数值转换成整数。预防式策略处理式策略处理时间短编码简单def

convert_int(s):

assert

isinstance(s,str),"参数s应当是str类型"

ifis_int(s):

return

int(s)

return

Nonedef

convert_int(s):

assert

isinstance(s,str),"参数s应当是str类型"

try:

return

int(s)

except

ValueError:

return

Nonedef

is_int(s):

s=s.strip()

ifs[0:1]in

'+-':

s=s[1:]

returns!=''

ands.isdigit()13.7断言断言用于应用程序和软件的开发过程中设置健全性检查的语句允许在代码中检查某些条件的正确性从而测试代码的正确性断言的语法为上面的断言与下面的语句功能一致断言工作机制当__debug__为假时,该语句无作用;当__debug__为真且检查的条件为真时,该语句同样无作用;当__debug__为真且检查的条件为假时,该语句起作用,会引发AssertionError,可选的参数说明了AssertionError异常产生的原因。assert

expression[,message]if

__debug__:

if

notexpression:

raise

AssertionError([message])断言作用断言作用:用于验证函数的前置或后置条件;或者函数的状态;或者进行代码的测试。例12编写函数计算圆的面积。frommathimportpidef

area(r

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论