try、except、else、finally

  • 结构

    try:
         Normal execution block
    except A as reason:
         Exception A handle
         print('出错了:'+str(reason))
    except B:
         Exception B handle
    except:
         Other exception handle
    else:
         if no exception,get here
    finally:
         print("finally")   
    
  • 执行顺序

    • 正常执行的程序在try下面的Normal execution block执行块中执行,在执行过程中如果发生了异常,则中断当前在Normal execution block中的执行跳转到对应的异常处理块中开始执行;
    • 从第一个except X处开始查找,如果找到了对应的exception类型则进入其提供的exception handle中进行处理,如果没有找到则直接进入except块处进行处理。except块是可选项,如果没有提供,该exception将会被提交给python进行默认处理,处理方式则是终止应用程序并打印提示信息;
    • 如果在Normal execution block执行块中执行过程中没有发生任何异常,则在执行完Normal execution block后会进入else执行块中(如果存在的话)执行。
    • 无论是否发生了异常,只要提供了finally语句,以上try/except/else/finally代码块执行的最后一步总是执行finally所对应的代码块。
  • 注意

    • 在上面所示的完整语句中try/except/else/finally所出现的顺序必须是try–>except X–>except–>else–>finally,即所有的except必须在else和finally之前,else(如果有的话)必须在finally之前,而except X必须在except之前。否则会出现语法错误。
    • 对于上面所展示的try/except完整格式而言,else和finally都是可选的,而不是必须的,但是如果存在的话else必须在finally之前,finally(如果存在的话)必须在整个语句的最后位置。
    • 在上面的完整语句中,else语句的存在必须以except X或者except语句为前提,如果在没有except语句的try block中使用else语句会引发语法错误。也就是说else不能与try/finally配合使用。
  • else的含义

    • 要么怎么样,要么不怎么样
      这种就是正常的if else语句。
    • 干完了能怎么样,干不完就别想怎样
      跟while、for配合使用,只有当循环结束才运行else内容,如果循环中break了,else则不执行。如以下代码:
        def showMaxFactor(num):
        count = num // 2  # python3的新的地板除
        while count > 1:
            if num % count == 0:
                print('%d最大公约数为%d'%(num, count))
                break
            count -= 1
        else:
            print('%d是素数'%num)
        
        showMaxFactor(25)
        showMaxFactor(11)
      
    • 如果没有问题,那就干吧
      这种情况都是except X或者except语句为前提,如果在没有except语句的try block中使用else语句会引发语法错误。也就是说else不能与try/finally配合使用。代码使用如最开始的例子。

raise、with

  • raise
    使用raise,程序自己引发异常。

    	raise ZeroDivisionError  # ZeroDivisionError
    	raise ZeroDivisionError('除数为0的异常')  # ZeroDivisionError: 除数为0的异常
    
  • with
    利用with语句减少异常处理的代码,不用最后使用finally进行文件的关闭。

  	try:
  	    f = open('d:\\blog\\data.txt', 'w')
  	    for line in f:
  	        print(f)
  	except OSError as reason:
  	    print('出错:'+str(reason))
  	finally:
  	    f.close()

  	try:
  	    with open('d:\\blog\\data.txt', 'w') as f:
  	        for line in f:
  	            print(f)
  	except OSError as reason:
  	    print('出错:'+str(reason))

  	'''
  	出错:not readable
  	出错:not readable
  	'''

异常种类及层次结构

  • 异常的种类主要如下:
异常名称异常说明
AssertionError断言语句(assert)失败
AttributeError尝试访问未知的对象属性
EOFError用户输入文件末尾标志EOF(Ctrl+d)
FloatingPointError浮点计算错误
GeneratorExitgenerator.close()方法被调用的时候
ImportError导入模块失败的时候
IndexError索引超出序列的范围
KeyError字典中查找一个不存在的关键字
KeyboardInterrupt用户输入中断键(Ctrl+c)
MemoryError内存溢出(可通过删除对象释放内存)
NameError尝试访问一个不存在的变量
NotImplementedError尚未实现的方法
OSError操作系统产生的异常(例如打开一个不存在的文件)
OverflowError数值运算超出最大限制
ReferenceError弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象
RuntimeError一般的运行时错误
StopIteration迭代器没有更多的值
SyntaxErrorPython的语法错误
IndentationError缩进错误
TabErrorTab和空格混合使用
SystemErrorPython编译器系统错误
SystemExitPython编译器进程被关闭
TypeError不同类型间的无效操作
UnboundLocalError访问一个未初始化的本地变量(NameError的子类)
UnicodeErrorUnicode相关的错误(ValueError的子类)
UnicodeEncodeErrorUnicode编码时的错误(UnicodeError的子类)
UnicodeDecodeErrorUnicode解码时的错误(UnicodeError的子类)
UnicodeTranslateErrorUnicode转换时的错误(UnicodeError的子类)
ValueError传入无效的参数
ZeroDivisionError除数为零
  • 异常层次结构

    BaseException
    +-- SystemExit
    +-- KeyboardInterrupt
    +-- GeneratorExit
    +-- Exception
      +-- StopIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      +-- 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
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning
    

个人博客:Loak 正 - 关注人工智能及互联网的个人博客
文章地址:Python基础(九)—异常except、else&with、异常的名称层次