python的异常机制

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)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值