zoukankan      html  css  js  c++  java
  • python之错误和异常

    try...except...finally

    try 语句块中异常发生点后的剩余语句永远不会到达(所以也永远不会执行). 一旦一个异常被引发, 就必须决定控制流下一步到达的位置. 剩余代码将被忽略, 解释器将搜索处理器, 一旦找到,就开始执行处理器中的代码.
    如果没有找到合适的处理器, 那么异常就向上移交给调用者去处理, 这意味着堆栈框架立即回到之前的那个. 如果在上层调用者也没找到对应处理器, 该异常会继续被向上移交, 直到找到合适处理器. 如果到达最顶层仍然没有找到对应处理器, 那么就认为这个异常是未处理的, Python 解释器会显示出跟踪返回消息, 然后退出.

    ps:避免把大片的代码装入 try-except 中然后使用 pass 忽略掉错误. 你可以捕获特定的异常并忽略它们, 或是捕获所有异常并采取特定的动作. 不要捕获所有异常,然后忽略掉它们.

    try:
        print 'try...'
        r = 10 / 0
        print 'result:', r
    except ZeroDivisionError, e:
        print 'except:', e
    finally:
        print 'finally...'
    print 'END'

    异常参数 e 是一个包含来自导致异常的代码的诊断信息的类实例。 print except:', e 其实是调用了e的__str__方法。

    如果只是想返回这个信息,可使用str()。

    def safe_float(object):
        try:
            retval = float(object)
        except (ValueError, TypeError), diag:
            retval = str(diag)
        return retval

    with及上下文管理

    参考链接:浅谈 Python 的 with 语句

    with 语句作为 try/finally 编码范式的一种替代,用于对资源访问进行控制的场合。
    with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。

    with语句的用法

    with context_expression [as target(s)]:
        with-body

    自定义上下文管理器

    ontext_manager.__enter__() :进入上下文管理器的运行时上下文,在语句体执行前调用。如果指定了 as 子句,with 语句将该方法的返回值赋值给 as 子句中的 target。

    context_manager.__exit__(exc_type, exc_value, exc_traceback) :退出与上下文管理器相关的运行时上下文,该方法返回一个布尔值表示是否对发生的异常进行处理。exc_type, exc_value, exc_traceback参数表示引起退出操作的异常,如果退出时没有发生异常,则3个参数都为None。发生异常时,如果不想处理异常,则将函数返回值设置为True;如果想处理异常,只需要将返回值设置为 False 就可以了(不要显示重新抛出异常,即不要重新抛出通过参数传递进来的异常)。之后,上下文管理代码会检测是否 __exit__() 失败来处理异常,并在退出该方法后重新抛出异常以由 with 语句之外的代码逻辑进行处理。(ps:如果该方法内部产生异常,则会取代由 statement-body 中语句产生的异常。)

    class DummyResource:
        def __init__(self, tag):
            self.tag = tag
            print 'Resource [%s]' % tag
        def __enter__(self):
            print '[Enter %s]: Allocate resource.' % self.tag
            return self      # 可以返回不同的对象
        def __exit__(self, exc_type, exc_value, exc_tb):
            print '[Exit %s]: Free resource.' % self.tag
            if exc_tb is None:
                print '[Exit %s]: Exited without exception.' % self.tag
            else:
                print '[Exit %s]: Exited with exception raised.' % self.tag
                return False   # 可以省略,缺省的None也是被看做是False</span>
    
    with DummyResource('Normal'):
        print '[with-body] Run without exceptions.'
    ----------------------------------------------------
    Resource [Normal]
        [Enter Normal]: Allocate resource.
        [with-body] Run without exceptions.
        [Exit Normal]: Free resource.
        [Exit Normal]: Exited without exception.
    
    
    with DummyResource('With-Exception'):
        print '[with-body] Run with exception.'
        raise Exception
        print '[with-body] Run with exception. Failed to finish statement-body!'
    --------------------------
    Resource [With-Exception]
        [Enter With-Exception]: Allocate resource.
        [with-body] Run with exception.
        [Exit With-Exception]: Free resource.
        [Exit With-Exception]: Exited with exception raised.
    
        Traceback (most recent call last):
          File "G:/demo", line 20, in <module>
           raise Exception
        Exception
    可以看到,正常执行时会先执行完语句体 with-body,然后执行 __exit__() 方法释放资源。with-body 中发生异常时with-body 并没有执行完,但资源会保证被释放掉,同时产生的异常由 with 语句之外的代码逻辑来捕获处理。

    raise抛出错误

    只有在必要的时候才定义我们自己的错误类型。如果可以选择Python已有的内置的错误类型(比如ValueError,TypeError),尽量使用Python内置的错误类型。 

    class FooError(StandardError):
        pass
    
    def foo(s):
        n = int(s)
        if n==0:
            raise FooError('invalid value: %s' % s)
        return 10 / n

    assert

    def foo(s):
        n = int(s)
        assert n != 0, 'n is zero!'
        #assert的意思是,表达式n != 0应该是True,否则,后面的代码就会出错。
        return 10 / n
    
    def main():
        foo('0')

    常见的错误类型和继承关系

    BaseException
     +-- SystemExit
     +-- KeyboardInterrupt
     +-- GeneratorExit
     +-- Exception
          +-- StopIteration
          +-- StandardError
          |    +-- BufferError
          |    +-- ArithmeticError
          |    |    +-- FloatingPointError
          |    |    +-- OverflowError
          |    |    +-- ZeroDivisionError
          |    +-- AssertionError
          |    +-- AttributeError
          |    +-- EnvironmentError
          |    |    +-- IOError
          |    |    +-- OSError
          |    |         +-- WindowsError (Windows)
          |    |         +-- VMSError (VMS)
          |    +-- EOFError
          |    +-- ImportError
          |    +-- LookupError
          |    |    +-- IndexError
          |    |    +-- KeyError
          |    +-- MemoryError
          |    +-- NameError
          |    |    +-- UnboundLocalError
          |    +-- ReferenceError
          |    +-- RuntimeError
          |    |    +-- NotImplementedError
          |    +-- SyntaxError
          |    |    +-- IndentationError
          |    |         +-- TabError
          |    +-- SystemError
          |    +-- TypeError
          |    +-- ValueError
          |         +-- UnicodeError
          |              +-- UnicodeDecodeError
          |              +-- UnicodeEncodeError
          |              +-- UnicodeTranslateError
          +-- Warning
               +-- DeprecationWarning
               +-- PendingDeprecationWarning
               +-- RuntimeWarning
               +-- SyntaxWarning
               +-- UserWarning
               +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning

     2015-05-27

  • 相关阅读:
    写在博客前面
    JavaAPI学习(一):API && String类 && Stringbuffer && StringBuilder
    Java面向对象(七):Object类 & 内部类 & 单例模式
    Java面向对象(六):抽象方法 & 接口 & 递归
    Java面向对象(五):OOP三大特性之多态 — final 关键字
    Java面向对象(四):OOP三大特性之封装与继承
    Java面向对象(三):Java权限修饰符—static关键字
    Java面向对象(二):成员变量—OOP中的内存管理—构造函数
    Java面向对象(一):方法—初识面向对象
    JavaSE学习(六):随机数—简单的排序算法
  • 原文地址:https://www.cnblogs.com/whuyt/p/4533098.html
Copyright © 2011-2022 走看看