Python3基础-异常处理
一 什么是 异常
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
1、语法上的错误 这种错误应该在程序运行前就修改正确
File "D:/PythonSu/pythonbase/网络编程/异常处理.py", line 9 if a == 1 ^ SyntaxError: invalid syntax
2、逻辑上的错误 ,常用的逻辑错误如下
#ZeroDivisionError: division by zero value = 1/0 #IndexError: list index out of range 下标索引超出序列编辑 list = [1,2] list[11] #TypeError: unsupported operand type(s) for +: 'int' and 'str' 传入对象类型与要求不符合 1+'2' #NameError: name 'a' is not defined 引用了一个未被赋值对象的变量 a #ValueError: invalid literal for int() with base 10: 'susu' 传入一个调用者不期待的值 num=input(">>>:") #输入 susu int(num) #KeyError: 'age' 试图访问字典里面不存在的键 dic = {'name':'susu'} dic['age'] #AttributeError: type object 'Foo' has no attribute 'x' 试图访问一个对象没有的属性 class Foo: pass Foo.x
二 异常处理
为了保证程序的容错性与可靠性,即在遇到错误时有相应的处理机制不会任由程序崩溃掉,需要对异常进行处理,处理的基本形式为
2.1 单分支
try: 被检测的代码块 except 异常类型: 检测到异常,就执行这个位置的逻辑
try: print("============") dic = {'name':'susu'} print(dic['age']) print("!!!!!!!!!!!!") except KeyError as e: print(e) """
执行结果如下 ============ 'age' """
2.2 多分支
try: 被检测的代码块 except 异常类型1: 检测到 异常类型1,就执行这个位置的逻辑 except 异常类型2: 检测到异常类型2,就执行这个位置的逻辑
try: print("============") num =input(">>>") res=int(num) dic = {'name': 'susu'} print(dic['age']) print("!!!!!!!!!!!!") except ValueError as e: print(e) except KeyError as e: print(e) print("====")
2.3 万能异常类型
try: 被检测的代码块 except 异常类型1: 检测到 异常类型1,就执行这个位置的逻辑 except 异常类型2: 检测到异常类型2,就执行这个位置的逻辑 except Exception: 其他类型的异常统一用此处的逻辑处理
2.4 在多分支except之后还可以跟一个else(else必须跟在except之后,不能单独存在)
try: 被检测的代码块 except 异常类型1: 检测到 异常类型1,就执行这个位置的逻辑 except 异常类型2: 检测到异常类型2,就执行这个位置的逻辑 ...... else: 没有异常发生时执行的代码块
2.5 try-except-finally类型
try: 被检测的代码块 except 异常类型1: 检测到 异常类型1,就执行这个位置的逻辑 except 异常类型2: 检测到异常类型2,就执行这个位置的逻辑 ...... else: 没有异常发生时执行的代码块 finally: 无论有无异常发生都会执行的代码块
备注:无论被检查的代码块是否触发异常,都会执行finally的子代码块。因此通过在finally的子代码块做一些回收资源的操作。例如 关闭打开的文件,关闭数据库连接等
2.5 raise 语句 ,raise后必须是一个异常的类或者异常的实例
num = input(">>>") if not isinstance(num,int): raise TypeError("num must be int")
2.6 内置异常不够用的情况下,通过继承内置的异常类来定义异常类
#方法1 class EgonExcept(Exception): #可以通过继承Exception【万能异常类型】来定义一个全新的异常 def __init__(self,value='The proxy souce is exhausted'): #定制初始化方法 super(EgonExcept,self).__init__() self.value = value def __str__(self): #定义该方法用来定制触发异常时打印异常值的格式 return "< %s >" %self.value raise EgonExcept() #方法2 class EgonExcept(BaseException): #可以通过继承BaseException来定义一个全新的异常 def __init__(self,value='The proxy souce is exhausted'): #定制初始化方法 self.value = value def __str__(self): #定义该方法用来定制触发异常时打印异常值的格式 return "< %s >" %self.value raise EgonExcept('自己定制的')
2.7 断言 aasert
num = '123' #表达式isinstance(num,int)返回值false 则触发异常AssertionError assert isinstance(num,int) if not isinstance(num,int): raise TypeError("num must be int")
三、什么时候使用异常处理
1、如果错误发生的条件是可预知的,应该用if 进行预防
2、如果错误发生的条件是不可预知的,即异常一定会触发,那么才应该用try..except语句来处理
eg: 下载网页内容的功能,网络发生延时之类的异常是很正常的。
import requests from requests.exceptions import ConnectTimeout #导入requests模块内自定义的异常 def get(url): try: response = requests.get(url,timeout=3) #超过3秒未下载成功则触发ConnectTimeout异常 res = response.text except requests.exceptions.ReadTimeout: print('连接请求超时') res = None except Exception: print('网络出现其他异常') res = None return res print(get('http://www.python.org'))