• 异常处理



    异常

    异常是程序发生错误的信号,程序一旦出错就会产生异常,异常是一个对象,若没有捕获异常并处理,则会抛出异常,程序的运行就会终止。


    异常的三部分

    • 1、异常的追踪信息,显示哪个文件,第几行出现错误。
    • 2、异常的类型,类型即类,一种类型标识一种错误。
    • 3、异常的内容,具体的错误信息。
    Traceback (most recent call last):   异常的追踪信息
      File "D:/Desktop/异常处理.py", line 67, in <module>
        xxx
    NameError: name 'xxx' is not defined
    异常类型     异常值
    

    异常类型

    不同的异常可以用不同的类型去标识,一个异常标识一种错误。常见的类型有:

    类型 含义
    BaseException 所有内置异常的基类
    Exception 所有内置的非系统退出类的异常都派生自此类
    AttributeError 访问一个对象不存在的属性
    IOError 输入/输出异常,基本上是无法打开文件
    ImportError 无法导入模块或包,基本上是路径问题或名称错误
    IndentationError 语法错误(的子类);代码没有正确对齐
    IndexError 索引超出序列边界
    KeyError 访问字典不存在的key
    KeyboardInterrupt Ctrl+c被按下
    NameError 调用未定义的变量
    SyntaxError 非法代码,语法错误
    TypeError 传入的对象类型与要求不符合
    UNboundLocalError 访问一个未定义的局部变量,通常是由于有一个同名的全局变量。
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的。

    处理异常

    为了增强程序的健壮性,即便是程序运行过程中出错了,也不要终止程序,而是将异常捕捉并处理,将出错信息记录到日志内。

    错误有两大来源:

    • 一、语法错误SyntaxError:必须在程序运行前就改正。
    • 二、逻辑错误。
      • 1、可预知错误:应在逻辑设计上就处理,通常用if判断。
      • 2、不可预知错误:使用异常处理语句。

    异常处理语句

    单异常

    try:
        子代码块
    except 异常类型:
        捕捉到异常后执行的代码.
        
    # 多异常都使用相同的处理方式
    try:
        子代码块
    except (异常类型1,异常类型2...):
        捕捉到异常后执行的代码.
        
    # 万能异常
    try:
        子代码块
    except Exception as e:  # Exception任意异常都能捕获到.
        所有的异常都会触发处理
    
    # 无法预知异常
    try:
        子代码块
    finally:
        无论被监测的子代码块有无异常发生,都会执行finally的子代码块。
    

    多异常

    try:
        子代码块
    except 异常类型1 as e:  # as会将异常信息赋值给后面的变量名.
        捕捉到异常类型1会执行的代码.
    except 异常类型2:
        捕捉到异常类型2会执行的代码.
    ...
    

    多异常使用相同处理方式

    try:
        子代码块
    except (异常类型1,异常类型2...) as e:
        捕捉到其中任一异常后执行的代码.
    except 异常类型3:
        pass
    ...
    

    任意异常

    通常用于某些无法预知异常类型的时候。

    try:
        子代码块
    except Exception:  # Exception能匹配任意异常
        任意异常都会触发执行.
    

    没有异常

    try:
        子代码块
    except 异常类型:
        pass
    else:
        没有异常则会触发执行
    

    无论是否有异常

    try:
        子代码块
    finally:
        无论是否有异常都会执行.
    

    finally不会处理异常,出现异常会先执行finally内的代码,然后终止子代码块执行。通常应该将被监测代码中回收系统资源的部分放到这里。比如关闭文件,关闭数据库连接等。

    完整语法

    try:
        # 有可能会抛出异常的子代码块,任何一行抛异常,其下的代码都不会执行。
        子代码1
        子代码2
        ...
    except 异常类型1 as e:
        捕捉到异常1后执行的代码.
    except 异常类型2 as e:  # as表示将异常信息赋值给后面的变量.
        捕捉到异常2后执行的代码.
    ...可以有多个except...
    else:
        若被监测的子代码块没有异常发生,则会执行else的子代码块。
    finally:
        无论被监测的子代码块有无异常发生,都会执行finally的子代码块。
    

    else不能单独与try配合使用;else可以不用,如果用必须在except后面使用。

    实例:

    try:
        f = open('a.txt','rb')
        f.write()
    except BaseException as e:
        print(e.args)  # ('write',)
    finally:
        f.close()
    

    以r模式打开文件不能向文件写入内容,所以会抛异常,e会接收到异常的内容。

    异常是附加给程序的一种异常处理的逻辑,与主要程序的工作是没有关系的,过多的异常处理语句会导致代码可读性变差,只有在错误发生的条件无法预知的情况下,才应该使用异常处理。


    主动抛异常

    不符合解释器的语法或逻辑规则时,解释器会自动抛异常,而对于违反开发者定义的各类规则时,则需要开发者自己主动抛出异常,主动抛异常使用的是raise关键字,raise后面必须是一个异常的类或者是异常的实例。

    def total(x,y):
        if not isinstance(x,int):
            raise TypeError('x must be int')
        elif not isinstance(y,int):
            raise TypeError('y must be int')
        return x + y
    
    total(1.1,2)  # TypeError: x must be int
    total(1,2.2)  # TypeError: y must be int
    

    自定义异常类型

    内置异常不符合期望时,可以通过继承内置的异常类来自定义异常类。自定义异常类必须继承内置异常类,通常是Exception类。

    class CommonError(Exception):
        # 初始化异常信息
        def __init__(self,msg='异常信息'):
            self.msg = msg
        
        # 定义触发异常类型时打印的异常信息格式
        def __str__(self):
            return f' {self.msg} '
        
    raise CommonError  # __main__.CommonError:  异常信息
    raise CommonError('自定义的异常信息')  # __main__.CommonError:  自定义的异常信息 
    

    也可以在特定异常的基础上扩展一个相关的异常.

    class CommonError(IOError):
        pass
    
    raise CommonError  # __main__.CommonError
    

    断言

    断言语句assert expression,断定表达式expression成立,否则触发异常AssertionError,与raise-if-not的语义相同.

    assert isinstance(10,int)
    assert 10 < 9  # AssertionError
    

    等同于

    if not isinstance(10,int):
        raise AssertionError
        
    if not 10 < 9:
        raise AssertionError
    

    断言语句通常用于程序调试过程中使用,实际生产环境中不应使用断言。

    参考文档:

    https://docs.python.org/zh-cn/3/library/exceptions.html?highlight=exception#Exception

  • 相关阅读:
    羊皮卷的故事第三章
    羊皮卷的故事第五章
    羊皮卷的故事第八章羊皮卷之一
    羊皮卷的故事第十一章羊皮卷之四
    羊皮卷的故事第四章
    羊皮卷的故事第十章羊皮卷之三
    羊皮卷的故事第九章羊皮卷之二
    羊皮卷的故事第十二章羊皮卷之五
    POJ3264 Balanced Lineup RMQ
    HDUPattern and Text 枚举
  • 原文地址:https://www.cnblogs.com/ChiRou/p/14277883.html
Copyright © 2020-2023  润新知