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

posted @ 2015-05-27 12:13  whu.yt  阅读(348)  评论(0编辑  收藏  举报