异常
异常介绍
当Python无法正常处理程序时就会发生一个异常,会影响程序的正常执行。异常也是Python对象,表示一个错误。
ab = int(input('请输入整数:')) # 当输入的内容为小数的时候会报错
cd = float(input('请输入整数:')) # 当不小心输入两个小数点的时候也会报错
print('1'*20)
ef = int(input('请输入整数:')) # 当输入小数时,会终止程序运行,下面的语句不会执行
print('1'*20)
异常捕获
当Python脚本有发生异常的可能时,就需要捕获异常,避免程序终止执行。
try:
正常程序执行此块代码
except:
抛出错误执行此代码块
练习:用键盘输入浮点数并进行输出,如果出现异常,就返回为1
try:
# 正常程序时执行代码块
ipt = float(input('请输入一个小数:'))
print(ipt)
except:
# 异常程序时执行代码块
print(1)
上述代码可以在程序出错时不让代码终止,但是不能输出异常的信息。
异常类型捕获
记录下具体异常种类,可以捕获具体的异常信息。
try:
pass
except 当前异常对象 as e: # 把当前异常对象赋值给e
print(e)
当前异常对象可以为:IndexError、ZeroDivisionError、ValueError、NameError
li = [1,2,3]
print(li[4]) # IndexError
print(2/0) # ZeroDivisionError
print(int('a')) # ValueError
prin() # NameError
比如出现索引错误。
try:
li = [1,2,3]
print(li[2]) # 程序没有问题时,正常运行,不执行except的代码
print(li[4]) # 程序运行错误时,才会执行except内部的代码
except IndexError as e:
print(e) # list index out of range
此时程序并未出现报错,而是输出了错误的类型。如果出现错误的类型不是IndexError,同样会出现终止程序运行。
try:
li = [1,2,3]
print(li[2])
print(int('a'))
except IndexError as e:
print(e) # 会报错:ValueError
可以通过help( __builtin __)查看所有的异常类型。
从上图中可以看到,所有的异常类型都继承了Exception类,Exception类可以捕获到它含有的所有子类(异常)。
try:
li = [1,2,3]
# print(li[3]) # list index out of range
print(int('a')) # invalid literal for int() with base 10: 'a'
except Exception as e:
print(e)
细分错误,非常有必要,一般用于载入日志,查看错误信息。在细分的异常种类下,最后才放入Exception,避免没有考虑到细小的错误信息。
try:
li = [1,2,3]
print(li[3]) # list index out of range
print(int('a')) # invalid literal for int() with base 10: 'a'
except IndexError as e:
print(e) # 载入日志
except ValueError as e:
print(e) # 载入日志
except Exception as e:
print(e)
try-except-else
如果抛出异常,执行except内部代码;如果程序正常,执行else内部代码。
程序正常运行时
try:
li = [1,2,3]
print(li[2])
except IndexError as e:
print(e)
except Exception as e:
print(e)
else:
print('程序正常时,执行的代码')
# 3
# 程序正常时,执行的代码
程序有异常时
try:
li = [1,2,3]
print(li[3])
except IndexError as e:
print(e)
except Exception as e:
print(e)
else:
print('程序正常时,执行的代码')
# list index out of range
try-finally
不管程序有无发生异常,都将执行finally内部代码。
try:
li = [1,2,3]
print(li[3])
except IndexError as e:
print(e)
except Exception as e:
print(e)
else:
print('程序正常时,执行的代码')
finally:
print('不管程序怎样,都会执行')
# list index out of range
# 不管程序怎样,都会执行
try:
li = [1,2,3]
print(li[2])
except IndexError as e:
print(e)
except Exception as e:
print(e)
else:
print('程序正常时,执行的代码')
finally:
print('不管程序怎样,都会执行')
# 3
# 程序正常时,执行的代码
# 不管程序怎样,都会执行
else和finally只能有一个。
主动触发异常
在实际开发中,在程序不满足某条件时,通常会主动抛出异常。
raise Exception(要抛出的异常信息)
练习 : 判断煎饼熟了没,当烹饪时间小于5时,则主动触发没熟异常;否则熟了
def CookJianbing(level):
if level < 5:
raise Exception('还没有熟')
try:
CookJianbing(6)
except Exception as e:
print(e)
else:
print('已经熟了')
记录日志的时候,把错误记录到相应的模块内。
例题:如果函数db() 有错误,主动抛出异常(raise),如果是调用函数自身的错误,就把错误载入日志中。
def db():
# 告诉使用者,此处有错误
raise Exception('数据库的错误')
def test1():
try:
db()
except Exception as e:
print('db函数错误:', e)
try:
li = [1,2,3]
print(li[3])
except Exception as e:
print('函数自身错误:', e)
test1()
# db函数错误: 数据库的错误
# 函数自身错误: list index out of range
自定义异常
当需要自定义满足一些规则时,就可以自定义异常。
自定义异常通过创建一个新的异常类,自定义名字与内容,并且需要继承Exception类实现,类的名字和内容的限定是由自己去编写的。
class NameError(Exception):
def __init__(self,msg):
self.info = msg
def __str__(self):
return self.info # 名字错误
# e = NameError('名字错误')
# print(e)
try:
# 用raise去主动触发异常
raise NameError('名字错误') # e = NameError('名字错误')
except NameError as e:
print(e)
断言
assert断言用于判断一个表达式,当表达式条件为False时触发断言异常AssertionError,不满足条件就直接抛出异常。
assert 断言(条件)
条件成立时,往下执行代码;条件不成立时,直接抛出异常AssertionError。
print('1'*20)
assert '1' == 1
print('1'*20)
注意,断言用于强制用户服从,可捕获,但是一般不捕获。