• 第十三篇:python之异常处理


    什么是异常

    异常就是程序运行时发生错误的信号,Python遇到错误后,会引发异常。如果异常对象并未被处理或捕捉,则程序就会用所谓的回溯(Traceback,一种错误信息)来终止执行。

    为了保证程序的健壮性与容错性,即在遇到错误时程序不会崩溃,我们需要对异常进行处理。

    下面编写一个同样功能的代码,对比做异常处理和不做异常处理的区别。

    '''不做异常处理'''
    num = int(input('请输入数字>>>')) #当输入的非数字时,则会触发异常,终止程序执行,下面的代码不会被执行,导致程序崩溃。
    print('你输入的整数是:{}'.format(num))

     如果发生的错误是可预知的,我们可以用if语句进行处理:在错误发生之前进行预防。

    '''做异常处理'''
    num = input('请输入数字>>>') #当输入的非数字时,则会触发异常,终止程序执行,下面的代码不会被执行,导致程序崩溃。
    if num.isdigit():
        print('你输入的整数是:{}'.format(int(num)))
    else:
        print('你输入的不完全是数字。')

    python的异常处理机制

     在所有的程序中,都会遇到异常,有些异常是代码编写的时候产生的,在前期过程中可能会直接导致程序无法运行。这一类的异常,在编写代码的时候,程序可以直接排查修改。但有些异常,是在程序运行过程中产生的,可能是与用户交互获取的数据无法识别,也或者是网络请求失败导致程序无法继续等等不可预知的异常。为了防止程序崩溃,这一类的错误,就需要程序员在编写的时候提前考虑到并进行相应的异常处理。每一门语言基本都有自己相应的异常防御机制,python尤其如此,不仅给了错误调试语句,还提供了庞大的内置异常类,让我们可以精准的针对不同异常给出不同的处理方式。

     异常分类

    异常名称 描述
    AssertionError 断言语句失败
    AttributeError 对象没有这个属性
    EOFError 没有内建输入,到达EOF 标记
    EnvironmentError 操作系统错误的基类
    IOError 输入/输出操作失败
    WindowsError 系统调用失败
    RuntimeError 一般的运行时错误
    OverflowWarning 旧的关于自动提升为长整型(long)的警告
    OSError 操作系统错误
    Warning 警告的基类
    DeprecationWarning 关于被弃用的特征的警告
    FutureWarning 关于构造将来语义会有改变的警告
    ImportError 导入模块/对象失败
    LookupError 无效数据查询的基类
    IndexError 序列中没有此索引(index)
    MemoryError 内存溢出错误(对于Python 解释器不是致命的)
    NameError 未声明/初始化对象 (没有属性)
    OverflowError 数值运算超出最大限制
    SyntaxWarning 可疑的语法的警告
    ZeroDivisionError 当除运算或模零在所有数值类型运算时引发
    PendingDeprecationWarning 关于特性将会被废弃的警告
    RuntimeWarning 当生成的错误不属于任何类别时引发
    UnicodeEncodeError Unicode 编码时错误
    UserWarning 用户代码生成的警告
    UnicodeTranslateError Unicode 转换时错误
    UnboundLocalError 访问未初始化的本地变量
    ReferenceError 弱引用试图访问已经垃圾回收了的对象
    KeyError 映射中没有这个键

    异常捕获

    异常:是指在程序执行过程中发生的一个事件,会影响程序的正常运行,当程序运行时系统接受到异常对象时,会寻找能处理这异常的代码并把当前异常对象交给其处理。所以一般需要进行捕获异常并处理。异常的捕获使用try/except/finally语句进行捕获操作。

    处理异常的语法结构:

    '''异常处理'''
    try:
        '''被检测的代码块'''
        num = input('请输入数字>>>')
        print('你输入的整数是:{}'.format(int(num)))
    except: #若不写异常类型,则默认捕获所有异常。
        print('你输入的不完全是数字')
    
    #可多分支捕获不同异常类型,进行相应的异常处理。
    try:
        '''被检测的代码块'''
        num = input('请输入数字>>>')
        print('你输入的整数是:{}'.format(int(num)))
    except TypeError:
        '''如果捕获到TypeError,就执行这个位置的逻辑'''
        print('捕获到TypeError时的处理逻辑')
    except ValueError as e:
        print(e)
    else:
        print('被检测代码正常运行,就执行这个位置的逻辑')
    finally:
        print('不管被检测代码是否有异常,该逻辑代码块都要执行,通常是进行清理工作')
    
    #可通过所以异常的基类BaseException,捕获所有异常,通过常规错误的基类Exception,捕获常规错误。
    try:
        num = input('请输入数字>>>')
        print('你输入的整数是:{}'.format(int(num)))
    except BaseException:
        print('你输入的不完全是数字')

    断言

    除了不可控的异常出现之外,有些代码需要特定的运行条件,那么,我们可以认为抛出异常。python中抛异常的方式有两种,断言,或者raise语句。其中,断言需要判定条件,而raise是直接后接需要抛出的异常类型。二者应用场合在我的理解中略有分别,断言常常使用于根据条件成立来决定抛异常的与否,通常用于为接下来执行的代码正常运行从而进行数据校验。例如,一个变量初始值为空,在程序运行到一半它从网络获取数据,如果没有数据,那么,程序无法执行。就可以使用断言来判定变量是否为空,如果为空,则直接抛异常,并给出告警。当然,raise可以实现同样功能,不过它需要一个if判别。因此,在代码使用上来讲,断言更为简洁,并且它也能被exception捕获。我们首先来看下断言机制。

    try:
        num = eval(input('请输入一个结果等于9的表达式:'))
    except BaseException:
        print('你输入的表达式不规范')
    else:
        """断言关键字使用,后接判定条件,如果条件成立,则无异常。不成立,抛AssertionError异常。<br>用","分割,后接给出的告警信息。告警信息也可以省略"""
        assert num == 9, "脑子是个好东西,我希望你有一个。好好计算!"
        print("你真聪明!")

    抛出异常

    程序的执行过程中如出现异常事件,可以生成一个异常对象,断言的语句用于已知的条件调试相对简洁。但有些异常时python定义的异常类里面存在的,为了方便快捷,我们可以直接抛出,无需定义异常信息,这时就需要raise来解决了。

    raise NameError("name error!")#抛出一个NameError异常,可以给一个打印信息,也可以不给
    #常规自定义具体异常信息应该尽量抛Exception类 这里仅做其他类示范。
    print("然而并没有错误!") #抛出异常后尝试打印点神马

    如上,raise可以直接抛出python自带的异常类,一看就知道哪里出了错误,所以如果不需要条件判定的是自定义异常信息,尽量抛Exception类。这样不至于混淆异常信息。以上代码都立足于功能示范,在实际使用中,一旦抛出异常,程序就会崩溃。所以常规的抛异常大多用于代码调试。如果是为了预防未知信息,抛异常应该出现try--except语句的try下属代码模块,然后用except捕获,再给出相应的解决方案。

    自定义异常类

    python允许你根据需求定义自己的异常类,但必须继承所异常类的基类BaseException。

    class EgonException(BaseException):
        def __init__(self,msg):
            self.msg=msg
        def __str__(self):
            return self.msg
    
    try:
        raise EgonException('类型错误')
    except EgonException as e:
        print(e)
  • 相关阅读:
    LeetCode——37. 解数独
    LeetCode ——42. 接雨水
    异常
    IO/FILE
    函数与模块
    选择与循环
    运算符
    字符串、列表、元组等
    SVTyper
    Error:Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-not69mld/pysam/
  • 原文地址:https://www.cnblogs.com/us-wjz/p/11001032.html
Copyright © 2020-2023  润新知