• Python - 异常处理


    异常与错误的概念

    错误:苹果内部坏了只能扔

    没法通过其他的代码进行处理的问题
    语法错误:比如 定义函数写成了 dfe xxx()
    这种错误,直接通过IDE或者解释器给出的提示进行修改

    逻辑错误:语法层面没有问题,但是自己设计的逻辑出现问题
    例如: if age<18: print(‘已经成年’)
    这种错误,IDE或者解释器无法帮我们检查出,只有通过代码测试进行排查

    异常:苹果只是脏了,洗洗还能吃

    程序在执行过程中,出现的未知错误;语法和逻辑都是正常的;可以通过其他代码进行处理修复

    例如:想获取一个数字,但用户输入了字符
    在x/y 中,输入的y为0

    类型

    除零异常
    1/0
    ZeroDivisionError

    名称异常
    print(name)
    NameError

    索引异常
    a = [1,2]
    a[3]
    IndexError

    键异常
    dic = {‘name’:‘sz’}
    dic[‘abd’]
    KeyError

    值异常
    int(‘abc’)
    ValueError

    属性异常
    name = ‘sz’
    print(name.xx)
    AttributeError

    迭代器异常
    it = ite([1,2])
    print(next(it))
    print(next(it))
    print(next(it))
    Stoplteration

    系统异常类继承树
    BaseExption 分为SystmExit KeyboardInter等等

    异常:
    系统一开始已经内置了一些应用场景,在我们写代码的过程中,一旦触发了这个场景,系统内部就会自动的向外界抛出这个问题,也就是我们所谓的异常

    预防:添加容错代码,加if 判断一下

    解决:有些场景无法语法,只能捕捉后处理掉,例子如下

    try:
        print(name)
    except NameError:
        print('名称有问题,请仔细检查')
    #不会报错了,有输出
    
    • 1
    • 2
    • 3
    • 4
    • 5

    语法

    try:
    	可能会出现异常的代码
    except 你要捕捉的异常1处理:
    	对这个异常的处理
    except 你要捕捉的异常2处理:
    	对这个异常的处理
    else:
    	没出现异常时做的处理
    finally:
    	不管有没有出现异常,都会执行的代码
    #else,finally这些词的顺序不可以变
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    当存在多次异常时,从上到下,捕捉到第一次异常后,就会往下匹配下去,不会多次检测

    取别名

    try:
        1/0
    except ZeroDivisionError as ze:
        print('xxx',ze)
    #输出:xxx division by zero
    
    • 1
    • 2
    • 3
    • 4
    • 5

    多个异常同时捕捉,用个元组

    try:
        1/0
        #print(name)
    except (ZeroDivisionError,NameError) as ze:
        print('xxx',ze)
    #输出:xxx division by zero
    
    try:
        #1/0
        print(name)
    except (ZeroDivisionError,NameError) as ze:
        print('xxx',ze)
    #输出:xxx name 'name' is not defined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    如果异常名称不确定,又想捕捉,可以直接写Exception

    try:
        1/0
        #print(name)
    except Exception as ze:
        print('xxx',ze)
    #输出:xxx division by zero
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    with语句

    适用于某一段代码之前预处理,执行某段代码之后清理操作
    无论这段代码有无异常,都能保证最后的清理操作得到执行

    例子:读取文件
    1,打开文件 2,读取文件 3,关闭文件
    如果2出错,3不会执行,导致文件无法关闭

    try:
        打开文件
        读取文件
    finally:
        关闭文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    with open(file) as F:
        读取文件
    #open 已经实习了打开与关闭
    
    • 1
    • 2
    • 3
    try:
        f = open('xx.jpg','r')
        f.readlines()
    finally:
        print('xxx')
        f.close()
    
    with open('xx.jpg','r') as f:
        f.readlines()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    上下管理器

    上面与下面有一段固定代码

    class Test:
        def __enter__(self):
            print('enter')
        def __exit__(self, exc_type, exc_val, exc_tb):
            print(self, exc_type, exc_val, exc_tb)
            print('exit')
    with Test():
        print('body')
    
    输出:
    enter
    body
    <__main__.Test object at 0x0000023E3C5CAFD0> None None None
    exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    class Test:
        def __enter__(self):
            print('enter')
            return 'xxx'
        def __exit__(self, exc_type, exc_val, exc_tb):
            print(self, exc_type, exc_val, exc_tb)
            print('exit')
    
    with Test() as x:
        print('body',x)
    #x输出上下管理器的返回值
    #return self 时,返回 body <__main__.Test object at 0x0000023E3C5CAFD0>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    contexlib模块

    生成器变成了上下管理器

    import contextlib
    @contextlib.contextmanager
    def test():
        print(1)
        yield 'xxx'
        print(2)
    with test() as x:
        print(3,x)
    
    输出:
    1
    3 xxx
    2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    Java客户端调用elasticsearch进行深度分页查询 (search_after)
    C++高级面试题:解释 C++ 中的行为参数化(Behavioral Parameterization)
    物料搬运装置及控制系统设计(CAD+PLC)
    《从0开始写一个微内核操作系统》6-GIC中断
    如何用webgl(three.js)搭建处理3D隧道、3D桥梁、3D物联网设备、3D高速公路、三维隧道桥梁设备监控-第十一课
    deployment的yaml说明
    什么是跨域以及为什么会出现跨域以及跨域的解决方案
    深入了解Eureka:微服务架构中的服务发现与注册中心
    如何检查Apache Kafka服务运行状态
    PostgreSQL数据库WAL——RM_HEAP_ID日志记录动作
  • 原文地址:https://blog.csdn.net/Sun123234/article/details/126843624