异常处理
一.关于异常处理
""" 程序错误分为两种: 语法错误 和 异常处理 语法错误:代码没有按照python规定语法去写,发明创造产生的错误 异常处理: 在代码语法正确的前提下,程序报错就是异常 """ # try ... except... 基础语法 用于解决程序异常问题 # raise 可以主动抛异常,异常类可以自定义
二、认识异常处理
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# IndexError 索引超出序列的范围 """ lst = [1,2,3,4] print(lst[100]) """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# KeyError 字典中查找一个不存在的关键字 """ dic = {"a":1} dic["asdf"] """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# NameError 尝试访问一个不存在的变量 """ print(name) """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# IndentationError 缩进错误 """ if 5 == 5: print(1) print(2) """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# AttributeError 尝试访问未知的对象属性 """ class A(): a = 10 obj = A() obj.b """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# StopIteration 迭代器没有更多的值 """ it = iter([1,2,3]) for i in it: pass res = next(it) """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# AssertionError 断言语句(assert)失败 """ 断言就是猜的意思 assert 和 if 之间的区别在于 assert 在断言失败时候,是直接报错,抛出异常,后面的代码直接终止了. if 在判断为False 的时候,不执行代码 """ assert 3>1 assert 3>1000 print(res) print("ok")
三、异常处理的基本语法
1、基本语法
""" try ... except ... 把有问题的代码放到try这个代码块当中 如果出现了异常,会直接执行except这个代码块中的内容 作用:防止异常抛错,终止程序. """
try : lst = [1,2,3] print(lst[90]) except: pass # print("这里有异常错误~")
2、带有分支的异常处理
class A(): a = 10 obj = A() try: # IndexError # lst = [1,2,3] # print(lst[90]) # KeyError # dic = {} # print(dic["a"]) # print(wangwen) obj.b() except IndexError: print("索引超出了范围") except KeyError: print("字典中没有这个键") except NameError: print("没有这个变量") except: print("有异常错误...")
3、处理迭代器异常错误
def mygen(): print("start ... ") yield 1 yield 2 yield 3 return 4 # 初始化生成器函数 -> 返回生成器对象 -> 简称生成器 gen = mygen() try: res = next(gen) print(res) res = next(gen) print(res) res = next(gen) print(res) res = next(gen) print(res) except StopIteration as e : # 为当前异常错误类StopIteration的对象起一个别名叫做e # 在StopIteration内部有__str__的方法 # 在打印对象时,直接获取生成器中的return的返回值. print(e) print("生成器停止迭代")
4、异常处理的其他写法
4.1、try ... finally ... 不论代码正确与否,都必须执行的代码放到finally当中.
"""一报错会终止掉程序,后面的代码不执行,有些必须要走的代码写在finally中""" print("<===============>") try: lst = [1,2,3] print(lst[90]) finally: print("被触发了..") print(123)
4.2、try .. except .. else ...
"""如果try这个代码块没有异常错误,执行else这个分支,反之就不执行""" print("<===============>") try: lst = [1,2,3] print(lst[90]) except: pass else: print("正常执行结束...")
4.3、try .. except .. else .. finally ..
try: lst = [1,2,3] print(lst[90]) except: print("异常处理222") else: print("正常执行结束...") finally: print("我被执行了111")
# (扩展) # for/while ... else .. 当循环遇到break异常终止循环时,不执行else分支 for i in range(10): if i == 5: break # pass else: print("循环结束")
四、raise 主动抛出异常
""" raise + 异常错误类 or 异常错误类对象 BaseException 所有异常类的父类(基类,超类) Exception 常见异常类的父类 """
1、基本语法
try: raise BaseException except BaseException: pass # 简写 try: raise except: print("有异常错误")
2、自定义异常类 MyException (务必继承父类 BaseException)
#(了解)系统底层获取行数和文件名的函数( 只有在程序异常时才能触发 ) def return_errorinfo(n): import sys f = sys.exc_info()[2].tb_frame.f_back if n==1: return str(f.f_lineno) #返回当前行数 elif n == 2: return f.f_code.co_filename #返回文件名 # 通过get_value 主动抛出异常 def get_value(n): try: raise except: return return_errorinfo(n) class MyException(BaseException): def __init__(self,num,msg,line,file): # 错误号 self.num = num # 错误信息 self.msg = msg # 错误行号 self.line = line # 错误文件 self.file = file sex = "雌雄同体" try: if sex == "雌雄同体": # raise + 异常错误类 或者 异常错误类对象 raise MyException(404,"醒醒吧老弟,人类没有雌雄同体~",get_value(1),get_value(2)) except MyException as e: # 对象.属性 print(e.num) print(e.msg) print(e.line) print(e.file)
五、反射(针对类对象或者模块)
"""概念: 通过字符串去操作类对象或者模块当中的成员(属性或者方法)"""
class Man(): pass class Woman(): pass class Children(Man,Woman): skin = "绿色" def eat(self): print("小孩一下生就拿了两串大腰子出来了") def drink(self): print("小孩一下生拿了两瓶勇闯天涯出来了") def __suger(self): print("小孩自个的糖糖是不给别人的...") obj = Children()
1、反射类对象中的成员
#hasattr() 检测对象/类是否有指定的成员
# 对象 res = hasattr(obj,"skin") print(res) # 类 res = hasattr(Children,"eat") res = hasattr(Children,"__suger") print(res)
2、getattr() 获取对象/类成员的值
# 对象 res = getattr(obj,"skin") print(res) # 通过对象反射出来的方法是个绑定方法 func = getattr(obj,"drink") func() # 类 # 通过类反射出来的方法是个普通方法 func = getattr(Children,"eat") func(1) # 反射的成员不存在时,可以设置一个默认值防止报错 res = getattr(obj,"abcdefg1234","该成员不存在") print(res) # 综合案例 """ strvar = input("请输入你要使用的方法") if hasattr(obj,strvar): func = getattr(obj,strvar) func() """
3、setattr() 设置对象/类成员的值
# 对象 setattr(obj,"eye","白色") print(obj.eye) # 类 setattr(Children,"sex","女性") print(Children.sex) print(obj.sex) #delattr() 删除对象/类成员的值 # 对象 # delattr(obj,"eye") # print(obj.eye) error # 类 # delattr(Children,"sex") # Children.sex
4、反射模块中的成员
import sys print(sys.modules) # 返回的是系统模块的一个字典 # 获取当前本模块的对象 (通过__main__这个键来获取) print(sys.modules["__main__"])
while True: selfmodule = sys.modules["__main__"] strvar = input("请输入你要反射的方法") if hasattr(selfmodule,strvar): func = getattr(selfmodule,strvar) func() else: print("没有这个方法")