Day08 异常

文章目录

    day08 异常

    1. 异常介绍

    每一种异常属于一个单独的类 所有的异常都继承字Exception 而Exception又继承自BaseException

    BaseException(所有异常的根) ├── Exception(绝大多数“常规错误/异常”的父类) │ ├── SyntaxError(语法错误) │ ├── ZeroDivisionError(除零) │ ├── IndexError(索引越界) │ ├── KeyError(字典键不存在) │ └── ... ├── SystemExit(程序退出信号) └── KeyboardInterrupt(用户按 Ctrl+C 中断)

    2. 异常处理介绍

    我们今天将会通过 try except else finally raise assert with 关键字处理异常

    我们所谓的异常处理 并不是避免 规避异常 而是当异常出现以后 我们使用Python提供的异常处理机制

    不让程序中断 继续执行完毕

    3. try-except处理异常

    """
        回顾异常中断程序的现象
        异常会导致程序中断 即后续的代码不再执行
    """
    
    num_1 = int(input("请输入被除数\n"))
    
    num_2 = int(input("请输入除数\n"))
    
    print(num_1 / num_2) # Python中除法  默认为float类型
    
    print("程序结束")
    
    

    使用try-except处理异常 try:结构内用于书写可能出现异常的代码 except:用于捕获异常

    try或者except不能单独使用 ​ try-except ​ try-except-else ​ try-except-finally ​ try-except-else-finally

    直接输出对象 相当于调用此对象的__ str __函数

    """
        使用try-except处理异常
        try:结构内用于书写可能出现异常的代码
        except:用于捕获异常
    
        try或者except不能单独使用
            try-except
            try-except-else
            try-except-finally
            try-except-else-finally
    
        直接输出对象 相当于调用此对象的__str__函数
    """
    
    
    try:
        num_1 = int(input("请输入被除数\n"))
    
        num_2 = int(input("请输入除数\n"))
    
        print(num_1 / num_2) # Python中除法  默认为float类型
    
    except ValueError as e:
        print("捕获到了值异常",e)
    
    print("程序结束")
    
    
    

    使用多个except捕获不同类型的异常

    """
        使用多个except捕获不同类型的异常
    """
    
    
    try:
        num_1 = int(input("请输入被除数\n"))
    
        num_2 = int(input("请输入除数\n"))
    
        print(num_1 / num_2) # Python中除法  默认为float类型
    
    except ValueError as e:
        print("捕获到了值异常",e)
    except ZeroDivisionError as e:
        print("捕获到了除数为零异常",e)
    
    print("程序结束")
    
    
    

    使用一个 except 处理多个不同类型的异常 将多个异常书写在一个元组中即可

    """
        使用一个 except 处理多个不同类型的异常
        将多个异常书写在一个元组中即可
    """
    
    
    try:
        num_1 = int(input("请输入被除数\n"))
    
        num_2 = int(input("请输入除数\n"))
    
        print(num_1 / num_2) # Python中除法  默认为float类型
    
    except (ValueError,ZeroDivisionError) as e:
        print("捕获到了异常",e,type(e))
    
    print("程序结束")
    
    
    

    因为所有的异常都继承自Exception 所以如果在except后边书写了 Exception

    那么将可以处理所有的异常 但是不推荐这样书写 因为代码可读性较差

    如果要书写多个exception处理多种异常 异常的书写顺序为先写子类 再写父类

    """
        因为所有的异常都继承自Exception 所以如果在except后边书写了 Exception
        那么将可以处理所有的异常 但是不推荐这样书写 因为代码可读性较差
    
        如果要书写多个exception处理多种异常 异常的书写顺序为先写子类 再写父类
    
    """
    
    
    try:
        num_1 = int(input("请输入被除数\n"))
    
        num_2 = int(input("请输入除数\n"))
    
        print(num_1 / num_2) # Python中除法  默认为float类型
    
    except  Exception  as e:
        print("第一个except处理异常",e)
    except ZeroDivisionError as e:
        print("捕获到了除数为零异常",e)
    except ValueError as e:
        print(e)
    
    
    print("程序结束")
    
    
    

    4. try-except-else处理异常

    使用else处理异常 else中的代码 表示上方的try结构 没有出现异常

    将会执行的代码

    else可以提高代码的可读性 可维护性

    """
        使用else处理异常 else中的代码 表示上方的tru结构 没有出现异常
        将会执行的代码
        else可以提高代码的可读性 可维护性
    
    """
    
    try:
        num_1 = int(input("请输入被除数\n"))
    
        num_2 = int(input("请输入除数\n"))
    
        result = num_1 / num_2
    
    except ZeroDivisionError as e:
        print("捕获到了除数为零异常",e)
    except ValueError as e:
        print(e)
    else:
        print("{0} / {1} = {2}".format(num_1, num_2, result))
    
    print("程序结束")
    
    
    
    
    

    5. try-except-else-finally处理异常

    finally中用于书写 不管是否出现异常 以及 异常是否被捕获到 都将执行的代码

    """
        finally中用于书写 不管是否出现异常 以及 异常是否被捕获到 都将执行的代码
    """
    
    
    try:
    
        list1 = [1,2,3]
    
        print(list1[3])
    
        num_1 = int(input("请输入被除数\n"))
    
        num_2 = int(input("请输入除数\n"))
    
        result = num_1 / num_2
    
    except ZeroDivisionError as e:
        print("捕获到了除数为零异常",e)
    except ValueError as e:
        print(e)
    else:
        print("{0} / {1} = {2}".format(num_1, num_2, result))
    finally:
        try:
            print(10 / 0)
        except ZeroDivisionError as e:
            print(e)
    
    
        print("程序结束")
    
    
    

    6. raise处理异常

    raise 用于抛出(创建)异常对象 用于在合适的时机 结束程序 由于代码中出现了严重的错误 而应该停止程序

    """
        raise 用于抛出(创建)异常对象
        用于在合适的时机 结束程序 由于代码中出现了严重的错误 而应该停止程序
    """
    
    
    def get_sum(num1, num2):
        if isinstance(num1, (int, float)) and isinstance(num2, (int, float)):
            return num1 + num2
        else:
            raise TypeError("类型不符合,必须为int或者float")
    
    try:
        print(get_sum("abc", 2))
    except TypeError as e:
        print(e)
    
    print("程序结束")
    
    
    """
        raise的使用
    """
    
    class Student:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self,name):
            self.__name = name
    
    
        @property
        def age(self):
            return self.__age
    
        @age.setter
        def age(self,age):
            if 1 <= age <= 120:
                self.__age = age
            else:
                raise ValueError("年龄必须在1~120之间")
    
    
    try:
        s1 = Student("赵四",130)
    except ValueError as e:
        print(e)
    
    
    print("程序结束")
    
    
    
    
    
    

    7.assert处理异常

    assert 断言 处理异常 assert 后边跟一个表达式

    assert 表达式 ,"描述异常"

    ​ 如果条件成立 则无事发生 ​ 如果条件不成立 则Python解释器会自动创建一个异常对象AssertionError类型 我们自行添加异常信息即可

    """
        assert 断言 处理异常
        assert 后边跟一个表达式
            如果条件成立 则无事发生
            如果条件不成立 则Python解释器会自动创建一个异常对象AssertionError类型 我们自行添加异常信息即可
    """
    
    
    def get_sum(num1, num2):
        assert isinstance(num1, (int,float)) and isinstance(num2, (float,int)) , "类型不符合,必须为int或者float"
        return num1 + num2
    
    try:
        print(get_sum("abc", 2))
    except AssertionError as e:
        print(e)
    
    print("程序结束")
    

    使用多个assert来处理程序中的异常

    """
        使用多个assert来处理程序中的异常
    """
    
    
    def get_sum(num1, num2):
        assert isinstance(num1, (int,float)) , f"num1类型不符合,输入的内容为:{repr(num1)},必须为int或者float"
        assert isinstance(num2, (float,int)) , f"num2类型不符合,输入的内容为:{repr(num2)},必须为int或者float"
        return num1 + num2
    
    try:
        print(get_sum( 2,"ab\t\nc"))
    except AssertionError as e:
        print(e)
    
    print("程序结束")
    

    8. 自定义异常

    当Python提供的异常不能满足我们的开发需求 这时 我们需要自定义异常 自定义异常的步骤: ​ 编写异常类 继承异常父类即可

    关于异常的类名: ​ 1.必须一Error单词结尾 通过名字展示出来非普通类 ​ 2.名字尽量简明扼要

    """
        当Python提供的异常不能满足我们的开发需求 这时 我们需要自定义异常
        自定义异常的步骤:
            编写异常类 继承异常父类即可
    
        关于异常的类名:
            1.必须一Error单词结尾 通过名字展示出来非普通类
            2.名字尽量简明扼要
    """
    
    class AgeRangeError(Exception):
        pass
    
    
    class Student:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self,name):
            self.__name = name
    
    
        @property
        def age(self):
            return self.__age
    
        @age.setter
        def age(self,age):
            if 1 <= age <= 120:
                self.__age = age
            else:
                raise AgeRangeError("年龄必须在1~120之间")
    
    try:
        s1 = Student("赵四",123)
    except AgeRangeError as e:
        print(e)
    
    print("程序结束")
    
    
    

    9. 异常的传递机制

    异常的传递 : 嵌套结构中 内层的异常 会先由内层结构处理

    如果可以处理 则异常处理结束 否则层层向外传递 直到处理完毕 或者 嵌套结构结束

    """
        异常的传递 : 嵌套结构中 内层的异常 会先由内层结构处理
        如果可以处理 则异常处理结束 否则层层向外传递 直到处理完毕 或者 嵌套结构结束
    """
    try:
        try:
            try:
                print(10 / 0)
            except ValueError  as e:
                print("最内层的except处理异常:",e)
        except ZeroDivisionError  as e:
            print("中间层的except处理异常:", e)
    except NameError as e:
        print("最外层的except处理异常:", e)
    
    
    print("程序结束")
    

    10. with处理异常

    with关键字 属于语法糖 就是为了简化对于资源的管理 所要编写的 try except finally等 模板代码 Python中的IO相关的异常 统一由OSError来处理

    """
        with关键字 属于语法糖 就是为了简化对于资源的管理 所要编写的 try except finally等 模板代码
        Python中的IO相关的异常 统一由OSError来处理
    """
    
    try:
        reader = open("a.txt","r",encoding="utf-8")
        print(reader.read())
    
        print(10 / 0)
    
    except OSError as e:
        print(e)
    finally:
        reader.close()
        print(reader.closed)
    
    
    
    
    

    使用with关键字可以更加简洁优雅的处理资源

    """
        使用with关键字可以更加简洁优雅的处理资源
    """
    
    try:
        with open("a.txt","r",encoding="utf-8") as reader:
            print(reader.read())
    except OSError as e:
        print(e)
    finally:
        print(reader.closed)
    
    print("---------------------------------------------------------------------")
    
    with open("a.txt", "r", encoding="utf-8") as reader:
        print(reader.read())
    
    
    
    end