引发异常过程:若执行try块中业务代码出现了异常,系统自动生成一个异常对象,异常对象会被提交给python解释器。
捕获异常过程:python解释器收到异常对象时,会依次寻找能处理该异常对象的except块(最可能的放最前面)。若找到匹配的,则将该异常对象交给该except块处理,若找不到则报错。
python常见异常类继承关系及异常关系参考
https://docs.python.org/3/library/exceptions.html#exception-hierarchy
inputStr=input("请输入除数:") try: result=20/int(inputStr) print("20除以%s的结果为:%g" % (inputStr,result)) except ValueError: print("输入非数值,请输入一个非0数字") except ArithmeticError: print("输入值为0,请输入一个非0数字") #测试结果 请输入除数:dsads200 输入非数值,请输入一个非0数字 请输入除数:0 输入值为0,请输入一个非0数字 请输入除数:100 20除以100的结果为:0.2可以使用一个except块捕获多种类型异常,其实就是构建多个异常类的元组,但这种报错可能过于笼统。
inputStr=input("请输入除数:") try: result=20/int(inputStr) print("20除以%s的结果为:%g" % (inputStr,result)) except (ValueError,ArithmeticError): print("输入了非数值或0,请输入一个非0数字") #测试结果 请输入除数:kkk 输入了非数值或0,请输入一个非0数字 请输入除数:0 输入了非数值或0,请输入一个非0数字 请输入除数:30 20除以30的结果为:0.666667python会将异常对象赋值给except块后的异常变量,程序可通过这些变量访问对象信息
inputStr=input("请输入除数:") try: result=20/int(inputStr) print("20除以%s的结果为:%g" % (inputStr,result)) except Exception as e: print("输入了非数值或0,请输入一个非0数字") #异常错误号和详细信息 print(e.args) #输出结果 请输入除数:0 输入了非数值或0,请输入一个非0数字 ('division by zero',)异常处理流程中还可添加else块,当try块中没有出现异常时,程序会执行else块中内容。(可以但没必要,没有异常通常直接放在try后执行就可以了)
inputStr=input("请输入除数:") try: result=20/int(inputStr) print("20除以%s的结果为:%g" % (inputStr,result)) except Exception as e: print("输入了非数值或0,请输入一个非0数字") else: print("未发生异常") #输出结果 请输入除数:100 20除以100的结果为:0.2 未发生异常异常其实是很主观的东西,除了明确会导致程序错误的报错外,也需要结合具体业务确定。例如设置密码时小于6位抛出异常,这就不是python默认的报错,属于自定义异常。
raise语句用于在程序中抛出自定义异常,通常有以下3种用法:
raise # 单独一个raise,抛出当前上下文中捕获的异常(例如except语句中),或默认抛出RuntimeError异常 raise 异常类 # 抛出指定异常类的默认实例 raise 异常对象 # 抛出指定异常对象自定义异常类
自定义异常类都应该继承Exception类或其子类,定义时通常指定其父类即可。
class MyException(Exception): pass3种用法最终抛出的都是异常实例,raise语句每次只能抛出一个异常实例,若未在except中捕获,程序会直接报错退出
inputStr=input("请输入除数:") try: num=int(inputStr) #若num>20则抛出自定义异常 if num>20: #引发默认RuntimeError异常 raise result=20/num print("20除以%s的结果为:%g" % (inputStr,result)) except ValueError: print("输入非数值,请输入一个非0数字") except ArithmeticError: print("输入值为0,请输入一个非0数字") except RuntimeError: print("num>20,抛出了自定义RuntimeError异常") #测试输出 请输入除数:21 num>20,抛出了自定义RuntimeError异常实际应用中,当一个异常出现时,可能无法单靠某个方法进行处理,而要由几个方法协作,此时可以通过except与raise结合实现。一个常见的例子是,应用一方面需将报错记入日志文件,另一方面还需返回其他告知用户报错信息。
class MyException(Exception): pass class Bid: #构造方法定义起拍价 def __init__(self,init_price): self.init_price=init_price #定义竞拍函数 def bid_func(self,bid_price): d=0.0 try: d=float(bid_price) except Exception as e: #此处只打印简单异常信息 print("类型转换出现异常",e) #再次抛出自定义异常进行详细处理 raise MyException("竞拍价必须为数值") if self.init_price>d: raise MyException("竞拍价不得低于起拍价") initPrice=d def main(): test=Bid(21.6) try: test.bid_func("yyy") test.bid_func(6) except MyException as e2: #再次捕获异常并进行处理 print("main函数中捕获的异常",e2) main() #测试输出 类型转换出现异常 could not convert string to float: 'yyy' main函数中捕获的异常 竞拍价必须为数值python提供了traceback模块处理异常传播轨迹,查看异常源头。
traceback模块提供了两个常用方法:
format_exc():将异常传播轨迹转换为字符串traceback.print_exc():将异常传播轨迹输出到控制台或指定文件print_exc()的完整形式是print_exception(etype,value,tb[,limit[,file]])
etype:指定异常类型value:指定异常值tb:指定异常traceback信息limit:限制显示异常的传播层数,若不设置默认全部显示file:将异常传播轨迹输出到指定文件,若不设置则输出到控制台 import traceback class MyException(Exception): pass def main(): first() def first(): second() def second(): third() def third(): raise MyException("自定义异常信息") try: main() except: #捕获异常并输出至控制台 traceback.print_exc() #捕获异常并输出至指定文件 traceback.print_exc(file=open('log.txt','a')) #输出如下 Traceback (most recent call last): File "E:/pytest02/var.py", line 19, in <module> main() File "E:/pytest02/var.py", line 7, in main first() File "E:/pytest02/var.py", line 10, in first second() File "E:/pytest02/var.py", line 13, in second third() File "E:/pytest02/var.py", line 16, in third raise MyException("自定义异常信息") MyException: 自定义异常信息输出至文件结果
报错栈应该从下往上看,报错源头是在third方法第16行,对应的正好是抛出异常部分
若不使用该模块,也不捕获异常,python编辑器会利用自带的with_traceback在控制台打出报错栈。
class MyException(Exception): pass def main(): first() def first(): second() def second(): third() def third(): raise MyException("自定义异常信息") main() #控制台报错信息 Traceback (most recent call last): File "E:/pytest02/var.py", line 16, in <module> main() File "E:/pytest02/var.py", line 5, in main first() File "E:/pytest02/var.py", line 8, in first second() File "E:/pytest02/var.py", line 11, in second third() File "E:/pytest02/var.py", line 14, in third raise MyException("自定义异常信息") __main__.MyException: 自定义异常信息