zoukankan      html  css  js  c++  java
  • 《python学习手册》第35章 异常的设计

    嵌套异常处理器

      其实我们主要需要搞清楚的问题应该是这样的,当异常发生的时候,无论是简单的异常处理还是复杂的异常处理,我们都应该能够清楚的了解到异常运行到哪里,被谁捕获了,现在控制权到了哪里了,下面我们来分析嵌套异常处理的例子来说明上面说的这些问题。

      以下是当异常发生的时候try/except和try/finally对于异常的处理: 

    下面我们将使用程序来看一下当异常发生的时候会出现什么状况:

    使用嵌套的try/except的情况:

    def action2():
        print(1+[]) #TypeError
    try:
        try:
            action2()
            print('inner try')
        except TypeError:
            print('inner except')
        print('outer try')
    except TypeError:
        print('outter except')

    运行结果如下

    inner except
    outer try

      我们主要的目的是要了解情况的控制权在什么地方:当action2引发一个TypeError的时候,内部try/excpt的try模块后面信息不会继续执行,转而执行except的信息,当except将这个信息捕获的时候,执行except里面的信息,然后这个时候程序的控制权转到了try/except外面,然后外面的try/except因为没有发生异常,所以不会执行except里面的代码,程序继续转到try/except外面

    try/finally是如何执行的

    try:
        try:
            raise IndexError
            print('inner try')
        finally:
            print('inner finally')
        print('outer try')
    finally:
        print('outer finally')

    执行后的结果如下:

    inner finally
    outer finally
    Traceback (most recent call last):
      File "D:applicationeclipseworkspaceyichangc4	3.py", line 3, in <module>
        raise IndexError
    IndexError

    说明当使用try/finally以后,当try当中出现错误的时候,执行完finally代码块以后,代码就会继续往上抛,不会进行错误的捕获,最终抛到了顶层,由默认异常处理器进行处理

    try/excpet/finally进行嵌套时候的代码:

    def raise1(): raise IndexError
    def raise2(): return
    def raise3(): raise TypeError
    for func in (raise1,raise2,raise3):
        
        try:
            print('inner try')
            try:
                func()
            except IndexError:
                print('inner except ')
                
            print('outer try')
        finally:
            print('outer finally')
        print('
    ')

    运行结果如下:

    inner try
    inner except 
    outer try
    outer finally
    
    
    inner try
    outer try
    outer finally
    
    
    inner try
    outer finally
    Traceback (most recent call last):
      File "D:applicationeclipseworkspaceyichangc4	4.py", line 9, in <module>
        func()
      File "D:applicationeclipseworkspaceyichangc4	4.py", line 3, in raise3
        def raise3(): raise TypeError
    TypeError

    异常的习惯用法

    1:异常不总是错误

    错误总是异常,异常不总是错误。其实在在程序运行的过程当中,我们需要异常来配合我们的程序继续运行。有些异常时一些信号而已,比如EOFError还有SystemExit和KeyboardInterrupt异常等。

    2:关闭文件和服务器连接

    包括数据库等连接等情况,其实都有一个关闭连接的过程,这个时候使用try/finally。现在,我们有有了新的选择,那就是使用with/as来进行。

    3:sys.exc_info

    当使用空的except的时候,可以和sys.exc_info结合使用,来输出一些有用的信息,当有处理器处理的时候,sys_exc_info会存有(type,value,traceback)信息,当没有处理器处理错误的时候会返回(None,None,None)信息。

    与异常有关的技巧

    1:应该包装什么异常

      其实,主要是关于我们对于异常的态度,不要我们学了异常以后,我们运行的任何代码又要加上异常处理,这样会让我们显得胆战心惊。我们有时候其实并不需要进行异常捕获,因为程序运行出现错误其实是我们需要的,我们可以修改这些错误。我们主要是在我们觉得经常会出现失败的地方进行异常捕获。try/finally则用在需要关闭的场所。在单个函数外面使用异常比在其内部使用多个异常好一些。

    2:捕捉太多

      当我们使用一个excpet的时候,我们可以捕获所有的异常,这样程序看上去异常的简洁,你也可以放心的运行你的代码,但是其实这个并不是很好的,我们应该能够尽可能精确地捕获我们需要的错误,否则,except会拦截我们程序不会出现的错误,分析下面的例子:

    mydic = {1:'a',2:'b'}
    try:
        x = mydic[3]
    except:
        x = None
    print(x)

      其实,我们的代码的原意是这样的,当我们出现KeyError的时候,我们的x的值为None。假如我们的字典名字出现了错误,我们想要引发异常或者做一点不一样的事情,但是这个时候,我们的代码还会让x的值为None。

    3:捕捉太少

      捕捉太少出现的一个问题是,当我们修改程序的时候,我们需要在except里面增加我们的异常,所以这个时候可以使用高一等级的异常,来应对这种变化的情况。

  • 相关阅读:
    光学镜头参数详解(EFL、TTL、BFL、FFL、FBL/FFL、FOV、F/NO、RI、MTF、TVLine、Flare/Ghost)
    三角函数公式
    技术工人的升华
    如何在apache启动的时候不输入ssl的密码
    汉字转拼音问题
    深入PHP内核(1) 引用
    如何把普通的exe服务器程序注册成windows 服务
    如何学习Yii
    横向同步问题
    多态的内幕(C++, C)语言两个版本
  • 原文地址:https://www.cnblogs.com/jiaxin359/p/7341457.html
Copyright © 2011-2022 走看看