目录
知识点
-
异常概述
-
定义
-
程序执行中的产生的错误,如索引越界、文件不存在
-
-
代码示例
-
变量未定义 print(a)
-
文件未找到 open("123.txt", "r")
-
-
-
异常类
-
定义
-
所有异常都是基类Exception的成员,它们都定义在exceptions模块中。 如果这个异常对象没有进行处理和捕捉,程序就会用所谓的回溯(traceback,一种错误信息)终止执行,这些信息包括错误的名称(例如NameError)、原因和错误发生的行号。
-
-
代码详解
-
规则
-
所有异常继承自基类 Exception
-
异常定义在 exceptions 模块中
-
未处理的异常导致程序回溯并终止
-
-
python标准异常类
-
一般
-
AssertionError: 断言失败
-
AttributeError: 访问未知属性
-
IndexError: 索引超出序列范围
-
KeyError: 字典中查找不存在的关键字
-
MemoryError: 内存溢出
-
NameError: 访问不存在的变量
-
OSError: 操作系统异常,如文件不存在
-
OverflowError: 数值运算超出限制
-
SyntaxError: Python语法错误
-
IndentationError: 缩进错误
-
TabError: 混用Tab和空格
-
SystemError: Python系统错误
-
SystemExit: Python进程关闭
-
TypeError: 类型间无效操作
-
UnboundLocalError: 访问未初始化的局部变量
-
ValueError: 传入无效参数
-
ZeroDivisionError: 除数为零
-
FileNotFoundError打开不存在的文件时
-
-
-
-
异常处理
-
捕获简单异常
-
原理
-
使用 try-except 语句,定义了监控异常的一段代码,并提供了处理异常的机制。
-
try: # 语句块 except: # 异常处理代码 [else:] #可有可无 #如果没有异常执行这块代码
-
-
示例
-
捕获用户输入非数字的异常
-
while True: try: x = int(input("请输入一个数字: ")) break except: print("您输入的不是数字,请再次尝试输入!")
-
这种方式try-except语句捕获所有发生的异常。但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息。因为它捕获所有的异常。
-
改进
-
while True: try: x = int(input("请输入一个数字: ")) break except ValueError: print("您输入的不是数字,请再次尝试输入!")
-
-
-
-
-
注意
-
如果你不想在异常发生时结束你的程序,只需在try里捕获它。 try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
-
-
-
异常处理except
-
处理多个异常类型
-
原理及代码格式
-
-
-
try工作原理
-
标记程序上下文,异常发生时跳转
-
当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。else子句必须放在所有的 except 子句之后。
-
-
代码示例
-
class Student(object): def __init__(self,name): self.name = name try: s1 = Student('Jenny') print(s1.age) print(a) open("123.txt", "r") except AttributeError: print('访问了不存在属性') except NameError: print('变量未被定义') except FileNotFoundError: print('文件不存在') except: print('有错误出现,程序非正常结束') else: print('程序正常结束')
-
-
-
终止行为finally
-
无论是否捕获异常,都执行的代码。在程序中,无论是否捕捉到异常,都必须要执行某件事情,例如关闭文件、释放锁等,可以用finally语句处理。通常情况下,finally用于释放资源。
-
代码格式
-
-
-
抛出异常raise
-
原理
-
显式引发异常
-
当程序出现错误,python会自动引发异常,也可以通过raise显式地引发异常。一旦执行了raise语句,raise后面的语句将不能执行
-
-
-
代码格式
-
Exception 是异常的类型(例如,NameError)参数,可以是标准异常,也可以是自定义异常。 args 是自已提供的异常参数。 最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。
-
示例
-
下标越界引发 IndexError
-
-
-
自定义异常
-
原理
-
继承 Exception 类
-
-
示例
-
NullPointException
-
-
-
断言assert
-
判断表达式,失败时引发 AssertionError
-
代码格式
-
示例
-
-
-
-
上下文管理器与with语句
-
with语句
-
引入
-
-
原理
-
with语句适用于对资源进行访问的场合。用于管理资源,确保执行清理操作
-
-
格式
-
with context_expr [as var]: with_body
-
context_expr:需要返回一个上下文管理器对象,该对象并不赋值给as子句中的 var。 var:可以是变量或者元组。 with_body:with语句包裹的代码块。
-
-
语句执行过程
-
(1)执行context_expr,生成上下文管理context_manager;
-
(2)调用上下文管理器的__enter__()方法,如果使用了as子句,就把__enter__() 方法的返回值赋值给 as 子句中的var;
-
(3)执行语句体with_body。
-
(4)无论在执行的过程中是否发生异常,都会执行上下文管理器的 __exit__() 方法。该方法负责执行程序的“清理”工作,如释放资源等。
-
(5)如果执行过程中没有出现异常,或者语句体中执行了break、continue或者return语句,则以None 作为参数调用__exit__()方法;如果执行过程中出现异常,则会使用sys.exc_info 得到的异常信息为参数调用__exit__()方法。
-
(6)出现异常时,如果__exit__()方法返回的结果为False,则会重新抛出异常,让with 之外的语句逻辑来处理异常,这是通用做法;如果返回True,则忽略异常,不再对异常进行处理。
-
-
-
上下文管理器
-
原理
-
上下文管理器是Python 2.5开始支持的一种语法,用于规定某个对象的使用范围,一旦进入或者离开使用范围,会有特殊的操作被调用。
-
-
上下文管理协议
-
__enter__: 进入上下文时调用,其返回值被放入with-as语句中as说明符指定的变量中。
-
_exit__(self, type, value, tb): 离开上下文时调用,处理异常
-
如果有异常出现,type、value、tb分别为异常的类型、值和追踪信息;如果没有异常,3个参数均设为None。此方法返回值为True或者False,分别指示被引发的异常得到了还是没有得到处理,如果返回False,引发的异常会被传递出上下文。
-
-
-
规则
-
运行时上下文
-
由上下文管理器创建,管理进入和退出操作
-
-
-
实验
- 实验目的:
- 理解异常的概念
- 掌握处理异常的几种方式
- 掌握with和as环境安装器的使用
- 掌握raise和assert语句,会抛出自定义的异常
- 实验内容:
说明:基础题为必做题,提高题为选做题
1.(基础题)在E盘新建my_file.txt文件,并右击该文件,选择‘属性’,将该文件设置为只读文件。编写程序,用w模式向该文件写数据,程序运行后产生PermissionError异常,提示“文件不允许写”。请结合异常处理,完成以上功能,并确保打开文件后的正常关闭。
代码:
# 基础题1:文件写入异常处理
try:
# 尝试以w模式打开一个只读文件进行写入
with open('E:\\my_file.txt', 'w') as file:
file.write('这是一段测试文本。')
except PermissionError:
print("文件不允许写")
finally:
# 由于使用了with语句,文件会在此处自动关闭
print("文件已正常关闭。")
2.(基础题)假设成年人的体重和身高存在此种关系:
身高(厘米)-100=标准体重(千克)
如果一个人的体重与其标准体重的差值在正负5之间,显示“体重正常”,其他则显示“体重超标”或体重不达标。编写程序,能处理用户输入的异常,并且使用自定义异常类来处理身高小于30cm、大于250cm的异常情况。请完善代码。
class Input_problem_Error(___(1)________):
'''自定义异常类来处理身高小于30cm、大于250cm的异常情况'''
def __init__(self,length,max_length,min_length):
self.length = length
___(2)________
___(3)________
def print_Info(self):
print(f'Input_problem_Error:你输入的身高是{self.length},'
f'不能少于{self.min_length}cm,不能高于 {self.max_length}cm')
try:
length = int(input('请输入你的身高(cm):'))
weight = int(input('请输入你的体重(kg):'))
standard_weight = length-100
diff_weigth = weight-standard_weight
if length >=30 and length <=250:
assert diff_weigth <=5,'体重超标'
___(4) diff_weigth >=-5,'体重不达标'
else:
raise Input_problem_Error(length,250,30)
except AssertionError as asError:
print(asError)
except Input_problem_Error:
p=___(5)________(length,250,30)
p.print_Info()
else:
print('体重正常')
# 基础题2:体重判断程序
class InputProblemError(Exception): # 自定义异常类
'''自定义异常类来处理身高小于30cm、大于250cm的异常情况'''
def __init__(self, length, max_length, min_length):
self.length = length
self.max_length = max_length
self.min_length = min_length
def print_Info(self):
print(f'Input_problem_Error: 你输入的身高是{self.length}cm, '
f'不能少于{self.min_length}cm,不能高于{self.max_length}cm')
try:
length = int(input('请输入你的身高(cm):'))
weight = int(input('请输入你的体重(kg):'))
standard_weight = length - 100
diff_weight = weight - standard_weight
if length >= 30 and length <= 250:
if -5 <= diff_weight <= 5:
print('体重正常')
else:
raise AssertionError('体重超标' if diff_weight > 5 else '体重不达标')
else:
raise InputProblemError(length, 250, 30) # 触发自定义异常
except AssertionError as asError:
print(asError)
except InputProblemError as p:
p.print_Info()