python中 异常

[TOC]

异常

异常基础

默认的异常处理器:

异常会向上返回到程序顶层,启用默认的异常处理器,打印标准出错消息(堆栈跟踪和引发的异常)并终止程序.

异常的角色:

错误处理,事件通知,特殊情况处理,终止行为,非常规流程控制

异常产生:

  • python引发

  • raise语句:

    • 显式的触发异常,raise关键字后跟着可选的要引发的异常类或者异常类的一个实例(异常总是类的实例)

    • raise接受任何类型的对象引用

    • 传递异常:raise不包括异常名称或额外数据值时,就重新引发当前异常

    • 异常链:可选的from子句,指定了另一个异常类或实例,附加到引发异常的__cause__属性.如果引发的异常没有捕获,python也将其作为标准出错消息的一部分.

    • 异常处理器内部引发一个异常时,将前一个异常附加到新的异常的__context__属性

    • 例子:

    excs = [IndexError, TypeError]
    try:
        raise excs[0]('附加信息')  # 列表引用,抛出异常时增加提示信息
    except:
        raise  # 重新引发IndexError异常
    except IndexError as e   
        raise TypeError('Bad!') from e  # from异常链 ,IndexError异常也会输出
  • assert语句(断言):

    • 可视为条件式的raise,其后的条件为假时,抛出AssertionError异常

    • 形式为’assert [,]’,项是异常的额外数据

    • 附加的功能,使用-0 pyhon命令行标志位,类似python-0 main.py就会从程序编译后的字节码中移除,优化程序,关闭assert.

    • 用来收集用户定义的约束条件

异常处理:

try:  # 标记当前的程序环境,发生异常时返回,执行第一个符合引发异常的except子句下的语句
    <statements>
except <name1>:  # 捕捉特定的异常.可以有多个except子句,从上到下,从左到右查看except子句
    <statements>
except (name1,name2):  # 捕捉任何列出的异常
    <statements>
except <name4> as <data>:  # 捕捉异常,并将变量名称分配给其实例化对象,可以访问实例中的数据和异常类中的方法
    <statements>
except:  # 捕捉所有异常类型.
    <statements>
else:  # 如果没有异常,就执行.有至少一个except存在才能存在
    <statements>
finally:  # 无论是否发生异常,都执行.与except子句必须有其一.
    <statements>

with/as环境管理器:

  • 用于定义必须执行的终止或’清理’行为,无论处理步骤中是否发生异常.支持丰富的基于对象的协议,可以为代码块定义支持进入和离开动作.强化一些内置工具,例如自动关闭文件,自动上锁开锁.

  • 基本格式:

with expression [as variable][,expression [as variable]]:  # expression返回一个对象,支持环境管理协议,可以用逗号语法指定多个
    with-block
  • 环境管理协议:

    • 环境管理器对象必须有__enter____exit__方法

    • __enter__方法一开始会被调用,如果as子句存在,返回值赋值给as子句中的变量,否则,丢弃(所以variable不一定是环境管理器对象,但很多情况下,__enter__返回的是self对象本身)

    • with代码块引发异常,__exit__(type, value, traceback)方法就会被调用,参数为sys.exc_info的返回值.__exit__返回值为假时,异常会重新引发,传递到with语句外面.否则,会终止.默认返回None,为假.

    • with代码块执行完没有异常也会调用__exit__,其参数都为None.

异常对象

基于类的异常特点:

  • 提供类型分类,对今后的修改有了更好的支持.用户通过类自定义异常,继承自内置异常类(Exception),用户定义的异常类最好有一个超类,包含其他的子类.

  • 附加了状态信息.sys.exc_info和异常实例的__class__属性可以识别具体异常类型

  • 支持继承.超类可以捕捉子类的异常.

内置异常类层次结构:

BaseException  # 异常的顶级根类
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception  # 与应用相关的异常的顶级根类,定义用户异常类时,这里继承
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      |    +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

默认打印和状态:

传递给异常类的任何构造函数参数都会保存在args元祖属性中,打印该实例时自动显示.

异常的设计

异常的嵌套:

python会挑选并执行具有相符的except最近的try

异常的习惯用法:

  • 所有的错误都是异常,但异常不总是错误,可作为信号

  • 函数信号条件,用于无法返回警示值以表明成功或失败的函数

  • 关闭文件或服务连接

  • 在try外进行调试:通过循环,except执行测试,错误发生后,仍保持函数处于激活状态,执行其他测试

  • sys.exc_info返回一个(异常类型, 异常值/实例,traceback追踪对象)的三元祖

异常有关技巧:

  • 捕捉过多:避免空except语句,会拦截到无关的系统异常.具体优于一般,具体容易处理.意图明显

  • 捕捉过少:使用基于类的分类.捕捉一般的超类,就可以新增和引发更为特定的子类,超类变成可扩展的异常分类.

猜你喜欢

转载自blog.csdn.net/qq_32392853/article/details/81603677