异常
定义:不正常。当python检测到一个错误时,解释器就无法继续执行下去,反而出现一些错误的代码,这就是异常。
捕获异常:
try:
可能出现问题的代码
except:
出现问题后需要执行的代码
[Python] 纯文本查看 复制代码 a = input("请输入一个被除数")
b = input("请输入一个除数")
c = int(a)/int(b)
print("商为:%g"%c)
在以上代码中,如果a,b输入纯数字(b除0外),是没有问题的,但是如果a输入的值为“a”,或者b输入的值为0,就会报错,按照以前学习的方法避免该情况的需要是进行条件判断,具体如下:
[Python] 纯文本查看 复制代码 a = input("请输入一个被除数")
b = input("请输入一个除数")
if a.isdigit() and b.isdigit():
if int(b) != 0:
c = int(a)/int(b)
print("商为:%g"%c)
else:
print("除数不能为0")
else:
print("输入类型错误")
这样可以避免解释器报错,但是这时会发现判断代码比核心业务代码占的比重还要大,代码重心发生了偏移,因此我们使用异常处理代替这些判断语句
[Python] 纯文本查看 复制代码 a = input("请输入一个被除数")
b = input("请输入一个除数")
try:
c = int(a)/int(b)
print("商为:%g"%c)
except:
print("输入类型有误/除数不能为0")
这样就可以使用异常处理机制处理错误了,但是这样不能明确具体的错误原因,因此我们可以使用多个except明确错误原因。
多个except的用法
[Python] 纯文本查看 复制代码 '''
try:
except:异常1
except:异常2
except:异常3
'''
a = input("请输入一个被除数")
b = input("请输入一个除数")
try:
c = int(a)/int(b)
print("商为:%g"%c)
except ValueError:
print("输入类型有误")
#except ZeroDivisionError: #可以写ZeroDivisionError的父类异常 如:Exception
except Exception:
print("除数不能为0")
使用多个except可以针对不同的异常输出不同的错误提示,异常可以写父类异常,但是注意顺序问题,父类异常要放在最后,避免无法捕获真正的异常原因。以上面代码为例,如果将Exception异常放在第一位,无论是数据类型原因还是除数不能为0都会被归为Exception异常,无法准确定位具体错误原因。
except的多个异常的用法
[Python] 纯文本查看 复制代码 '''
try:
except:(异常1,异常2,异常3,。。。。)
'''
a = input("请输入一个被除数")
b = input("请输入一个除数")
try:
c = int(a)/int(b)
print("商为:%g"%c)
except (ValueError,ZeroDivisionError,Exception) as e:
print(type(e)) #查看异常类型
print(e.args) #查看错误信息
print("遇到异常")
这是使用的except多个异常的用法,可以将多个异常放到一个元组中,如果异常类型属于元组中的任一类型,就会执行except下代码,这种方式对类型顺序没有要求,而且可以将捕获到的错误信息存储到变量中,便于查看,可以查看错误类型、错误信息提示等。
try-except-else-finally
[Python] 纯文本查看 复制代码 file = open("123.txt","w",encoding="utf-8")
file.write("Hello")
file.write("World")
file.write([1,2,3]) #write 只能将字符串类型数据写入到文件中
print("写入完毕")
file.close()
print("关闭文件,谢谢使用")
这段代码执行时会报错,因为write 只能将字符串类型数据写入到文件中,不能写入列表。但同时又要需要在错误之后将后两行代码必须执行,这时就可以使用try-except-else-finally方法处理该异常。
[Python] 纯文本查看 复制代码 file = open("123.txt","w",encoding="utf-8")
try:
file.write("Hello")
file.write("World")
file.write([1,2,3]) #write 只能将字符串类型数据写入到文件中
except:
print("写入失败")
else:
print("写入完毕")
finally:
file.close()
print("关闭文件,谢谢使用")
这样就可以将最后两行代码必须执行而且解释器也不会报错。
异常的传递
[Python] 纯文本查看 复制代码 def test01():
print("-"*10+"test01开始"+"-"*10)
print(aa)
print("-"*10+"test01结束"+"-"*10)
def test02():
print("-"*10+"test02开始"+"-"*10)
test01()
print("-"*10+"test02结束"+"-"*10)
def test03():
print("-"*10+"test03开始"+"-"*10)
try:
test02()
except:
pass
print("-"*10+"test03结束"+"-"*10)
test03()
运行结果为:----------test03开始----------
----------test02开始----------
----------test01开始----------
----------test03结束----------
我们可以看出这段代码中函数test01中有一个错误print(aa),python中代码是从上到下运行的,调用test03,会打印test03开始,然后调用test02,会打印test02开始,然后调用test01,打印test01开始,这时print(aa)会出错,但是加入了异常处理,处理结果是pass,则会直接停止test02的调用,直接打印test03结束。
如果把异常处理去掉,我们同样可以看到解释器的运行轨迹
同样可以看出现调用test03,在调用test02,最后调用test01报错。
自定义异常及抛出自定义异常
自定义异常需要创建一个类,成为一个异常的子类。
抛出异常需要关键字raise。
[Python] 纯文本查看 复制代码 class GenderException(Exception): #自定义异常
def __init__(self):
super().__init__()
self.errMsg = "性别只能设置成男或女" #错误提示
class Student():
def __init__(self,name,gender):
self.name = name
self.setGender(gender)
def setGender(self,gender):#设置性别,只能为男或女
if gender == "男" or gender =="女":
self.__gender = gender
else:
raise GenderException
def getGender(self): #获取异性别
return self.__gender
def ShowInfo(self):
print("我叫:%s 性别:%s"%(self.name,self.__gender))
try:
stu = Student("学生1","12123")
except GenderException as e:
print(type(e))
print(e.errMsg)
在这段代码中,先自定义了一个异常类GenderException,继承了父类Exception,然后针对“性别只能为男或女”,在构造函数__init__和设置性别setGender中抛出异常,在执行时使用try-except进行了异常处理。 |