python的异常机制
一、python的异常机制
1、什么是异常,常见异常类型
异常机制是指程序运行过程中出现错误而进行处理操作,一般程序运行错误会停止运行并发送错误信息,如果设置了异常机制,那么当程序运行错误的时候,可以捕捉到异常并进行处理,来让程序处于运行状态。
异常信息例如:
def my_test(a):
def my_test2(b):
return a + b
return my_test2()
if __name__ == '__main__':
p = my_test(1)
q = my_test(2)
print(p(100))
print(q(100))
##运行结果
D:\python-test\venv\Scripts\python.exe D:/python-test/venv/test2.py
Traceback (most recent call last):
File "D:/python-test/venv/test2.py", line 7, in <module>
p = my_test(1)
File "D:/python-test/venv/test2.py", line 4, in my_test
return my_test2()
TypeError: my_test2() missing 1 required positional argument: 'b'
Process finished with exit code 1
从上述报错中可以看出,traceback是异常跟踪的信息,从”File “D:/python-test/venv/test2.py,,File “D:/python-test/venv/test2.py”,”, line 7“ 中得知错误在”test2.py“文件的第七行,第四行, ”p = my_test(1), return my_test2()“ 是程序错误的具体位置,”TypeError: my_test2() missing 1 required positional argument: 'b“ 错误类型为”TypeError“,缺少必须的位置参数”b“,
python的异常是由类定义的,所有的异常都来自于”Exception“类,不同类型的异常都继承于bashException类
枚举几个常见的异常类,如下:
IOError:输入输出异常,如无法打开文件
ImportError: 无法加载模块和包
IndentaitionError: 语法错误,没有对齐等
IndexError: 下标索引超出界限
KeyError: 访问字典key不存在
NameError:访问一个没有生命的变量或者对象
TypeError:传入对象类型个定义不符
TabError: tab和空格混用
ValueError:传入无效的参数或者数值
MemoryError:内存溢出错误
UnicodeError: 字符集错误
OverflowError: 数值超出最大限制
SyntaxError: 语法错误,
UnboundLocalError:访问一个还未被设置的局部变量
2、捕捉异常
完整的异常机制语法由4个关键字组成,try,except,else,finally,try和except是必须的,
可以分为五类,以try…except 和try…else 为例,其他的用法自行查找
1、try…except
2、try…finally
3、assert
4、with…as
5、try…else
try:检测代码是否出现异常,可以是全部代码或者部分代码
except:用于捕获异常信息并对异常信息进行处理,可以在关键词后指定捕捉的类型
else:如果try没有检测到异常,就执行else定义的代码
finally:不管try是否检测到异常,执行完except和else的代码后,会自动执行finally的代码
例如:
def my_test(a):
def my_test2(b):
return a + b
return my_test2()
if __name__ == '__main__':
try:
q = my_test(2)
print(q(100))
except TypeError as err:
print ('this is TypeError')
else:
print ('已执行else')
finally:
print ('已执行finally')
##执行结果
this is TypeError
已执行finally
因为有异常所以不执行else,如果没有异常则执行else、finally,可以设置多个except。
异常机制可以支持多个异常嵌套,但是不建议,视业务而定,例如:
def my_test(a):
def my_test2(b):
return a + b
return my_test2()
if __name__ == '__main__':
try:
q = my_test(2)
print(q(100))
except TypeError as err:
print ('this is TypeError')
except NameError as err:
try:
print ('我是嵌套的代码块')
except IOError as err:
print ('我是嵌套的异常')
else:
print ('已执行else')
finally:
print ('已执行finally')
2、自定义异常
自定义异常,除了检测错误之外,还可以用于代码的布局涉及和程序的逻辑控制,通过抛出异常执行不同的代码块,由关键字raise实现,关键词后边填写异常的类型和异常信息,例如:
def my_test(a):
def my_test2(b):
return a + b
return my_test2
if __name__ == '__main__':
try:
q = my_test(2)
print(q(100))
raise NameError
except TypeError as err:
print ('this is TypeError')
except NameError as err:
print ('this is NameError')
else:
print ('已执行else')
finally:
print ('已执行finally')
#输出结果
102
this is NameError
已执行finally
由raise抛出NameError的异常,所以except捕捉到 并执行代码块,所以输出结果为 NameError
NameError 是一个已经定义好的异常类,也可以自己定义异常类,但是必须继承Exception
数字的异常类,仅作为例子:
class NumberError(Exception):
pass
class xixi(NumberError):
def __init__(self,num_A,num_B):
self.num_A = num_A
self.num_B = num_B
def __str__(self):
return f"本函数只算数字!"
#__str__(self) 实现类到字符串的转化
def test(a,b):
try:
if (type(a) != int or type(b) != int):
raise xixi(a,b)
except Exception as err:
##except Exception as err 因为Exception是父类,所以此时表示任意错误
print(err)
else:
c = a + b
print (c)
if __name__ == '__main__':
test(1,2)
3、例子”狼人杀游戏“
主要有,狼人、间谍、村民组成,相互猜测身份,条件如下:
1、自定义2个异常类,用来判断错误次数和判断胜利的条件
2、定义玩家和角色,随机匹配,每一次游戏不能重复
3、每个玩家只能猜2此,超过5次游戏结束
4、才对了,继续猜,全部才对了游戏胜利并结束。
例如:
import random
class NumberError_1(Exception):
pass
class NumberError_2(Exception):
pass
class test_1(NumberError_1):
def __str__(self):
return ('恭喜你全部猜对了')
class test_2(NumberError_2):
pass
def __str__(self):
return ('回答错误,超过5次,游戏结束')
#定义玩家和角色为列变,然后随机获取列表中的内容
wanjia = ['小马','小贾','小童','小李']
juese = ['预言家','狼人','猎人','村民','守卫','女巫']
wanjia_so = random.sample(wanjia,len(wanjia))
juese_so = random.sample(juese,len(juese))
#定义字典用于存储玩家和角色的对应关系,随机对应
dict1 = {}
for i in range(len(wanjia_so)):
dict1[wanjia_so[i]] = juese_so[i]
# print (dict1)
#定义变量用于计数
try:
a = 0
b = 0
for n in wanjia_so:
print('可以选择的角色有:预言家,狼人,猎人,村民,守卫,女巫' )
for j in range(2):
p_input = input('你认为' + n + '玩家的角色是:')
if p_input == dict1[n]:
a += 1
print('恭喜你猜对了')
else:
print('猜错了,你还有' + str(1 - j) + '次机会')
b += 1
#print (b)
if b > 3 :
raise test_2
if a == n:
raise test_1
except Exception as errorinfo:
print(errorinfo)