zoukankan      html  css  js  c++  java
  • python异常处理

          Python使用try语句实现异常处理。try语句包围着可能引发异常的其他语句。try语句以关键字try开头,后续一个冒号(:)和一个可能在其中引发异常的代码。try语句可指定一个或多个except子句,它们紧接在try suite之后。每个except子句都指定了零个或多个异常类名,它们代表要由except子句处理的异常类型。可在except子句中指定一个标志符,程序用它引用被捕捉的异常对象。处理程序利用标识符从异常对象获取也异常有关的信息。如果except子句中没有指定异常类型,就称为"空白except子句"。这种子句会捕捉所有异常类型。在最后一个except子句之后,可选择性地添加一个else子句。如果try suite中的代码没有引发异常,就会执行else子句中的代码。如果try语句没有指定except子句,那就必须包含一个finally子句----该子句肯定会执行,无论是否发生异常。
        
        在try语句中同时包括except和finally子句是语法错误,可接受的组合形式只有:

    1 try:        
        ......    #可能得到异常的语句
       except     #锁定是哪种异常  (可以有多个except语句)             except Exception,e:  #捕获所有异常信息传递给变量 e
        ......    #出现异常的处理方法
    
    2 try:
        ......
       except
        .......
       else
        ......
    
    3 try:
        ......
      finally    #仅检查异常并做一些必要的清理工作  (仅能有一个finally语句)
        ........

          一旦程序代码导致异常,或Python解释器检测到问题,代码或解释器就会“引发”一个异常。有的程序员将程序中发生异常的位置称为“引发点”。异常是一些类的对象,这些类都是从Exception类继承的。如果在一个try suite中发生异常,这个try suite会立即“超时”(即立即终止),程序控制权会移交给try suite之后的第一个except处理程序(如果有的话),接着解释器搜索可对这种异常类型进行处理的第一个except处理程序。解释器为了确定相匹配的except,需要将引发的异常的类型与每个except处理程序的异常类型比较,直到最终发现相匹配的为止。如类型完全一致,或引发的异常的类型是except处理程序的异常类型的一个派生类,就表明发生了匹配。如果try suite中没有发生异常,解释器将忽略用于try语句的异常处理程序,并执行try语句的else子句(如果有的话)。如果没有发生异常,或者某个except子句成功处理了异常,程序会从try语句之后的下一个语句恢复执行。如果在某个语句中发生了一个异常,但该语句不在一个try suite 中,而是一在一个函数中,那么包含那个语句的函数会立即终止,解释器会试图在(发出)调用(的)代码中查找一个封闭的try语句,这个过程称为“堆栈辗转开解”(Stacking Unwinding)。

     ----------------------------------------------------------------------------------------------

    python shell

    >>> open('abc.txt','r')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IOError: [Errno 2] No such file or directory: 'abc.txt'

      打开一个不存在的文件abc.txt 文件,当系统找不到abc.txt 文件时,就会抛出给我们一个IOError类型的错误,No such file or directory:abc.txt (没有abc.txt这样的文件或目录)

     

    Try...except...

     

      假如,我们已经知道这种类型的错误,那么就可以通过一个异常扑捉来扑捉这个错误。我们可以通过try...except 来接收这个错误。打开文件写入:

    try:
        open("abc.txt",'r')
    except IOError:
        pass 

       再来运行程序就会看不到任何错误,因为我们用except 接收了这个IOError错误。pass 表示实现了相应的实现,但什么也不做。

      假如我不是打开一个文件,而是输出一个没有定义的变量呢? 

    try:
        print  aa
    except IOError:
        pass 

    显然,在上面的代码中我并没有对aa 赋值,运行结果:

    Traceback (most recent call last):
      File "/home/fnngj/py_se/tryy.py", line 3, in <module>
        print  aa
    NameError: name 'aa' is not defined

      我们已经用except 接收错误了,为什么错误还是还是抛出来了。如果你细心会发现这一次的错误类型是NameError ,而我接收类型是IOError ,所以要想接收这个print的错误,那么需要修改接收错误的类型为NameError

      虽然,我知道print 语句是可能会抛一个NameError 类型的错误,虽然接收了这个类型错误,但我不知道具体的错误提示信息是什么。那么,我能不能把错误信息打印出来呢?当然可以:

    try:
        print  aa
    except  NameError, msg:
        print  msg

      我们在接收错误类型的后面定义一个变量msg用于接收具体错误信息, 然后将msg接收的错误信息打印。再来运行程序:

    name 'aa' is not defined

    现在只打印了一行具体错误信息。

      

    异常的抛出机制:

    1、如果在运行时发生异常,解释器会查找相应的处理语句(称为handler).

    2、要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看那里能不能处理。

    3、如果在最外层(全局“main”)还是没有找到的话,解释器就会退出,同时打印出traceback以便让用户找到错误产生的原因。

     

    注意:虽然大多数错误会导致异常,但一个异常不一定代表错误,有时候它们只是一个警告,有时候它们可能是一个终止信号,比如退出循环等。

     

     

    try...finally...

     

    try...finally...子句用来表达这样的情况:

    我们不管线捕捉到的是什么错误,无论错误是不是发生,这些代码“必须”运行,比如文件关闭,释放锁,把数据库连接返还给连接池等。 

    创建文件poem.txt

    tryf.py

    复制代码
    import time
    
    try:
        f = file('poem.txt')
        while True: # our usual file-reading idiom
            line = f.readline()
            if len(line) == 0:
                break
            time.sleep(2)
            print line,
    

    finally: f.close() print 'Cleaning up...closed the file'
    复制代码

    运行程序(在windows命令提示符或linux终端下运行):

    复制代码
    ...$ python tryf.py 
    abc
    efg
    ^CCleaning up...closed the file
    Traceback (most recent call last):
      File "tryy.py", line 18, in <module>
        time.sleep(2)
    KeyboardInterrupt
    复制代码

      程序读poem.txt文件中每一行数据打印,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样做的原因是让程序运行得慢一些。在程序运行的时候,按Ctrl-c中断/取消程序。

      我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执行,把文件关闭。

     

     

    到目前为止,我们只讨论了如何捕捉异常,那么如何抛出异常呢?

     

    Raise抛出异常

     

    使用raise来抛出一个异常:    主动抛出一个异常,想让程序停止,可以主动抛出一个异常,与exit相比:有明确的原因

    tryr.py

    #coding=utf-8
    filename = raw_input('please input file name:')
    
    if filename=='hello':
        raise NameError('input file name error !')

      程序要求用户输入一个文件名,如果用户输入的文件名是hello ,那么抛出一个NameError的异常,用户输入hello 和NameError异常之间没有任何必然联系,我只是人为的通过raise来这样定义,我当然也可以定义称TypeError ,但我定义的异常类型必须是python提供的。

     

    ---------------------------------------------------------------------------------------------------------------------------

    1、try...except...语句

    我们尝试读取用户的一段输入。按Ctrl-d,看一下会发生什么。

    >>> s = raw_input('Enter something --> ')
    Enter something --> Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    EOFError

    Python引发了一个称为EOFError的错误,这个错误基本上意味着它发现一个不期望的 文件尾 (由Ctrl-d表示)

    接下来,我们将学习如何处理这样的错误。

    我们可以使用try..except语句来处理异常。我们把通常的语句放在try-块中,而把我们的错误处理语句放在except-块中。

    处理异常

    #!/usr/bin/python
    # Filename: try_except.py


    import sys

    try:
        s = raw_input('Enter something --> ')
    except EOFError:
        print ' Why did you do an EOF on me?'
        sys.exit() # exit the program
    except:
        print ' Some error/exception occurred.'
        # here, we are not exiting the program

    print 'Done'

    输出

    $ python try_except.py
    Enter something -->
    Why did you do an EOF on me?

    $ python try_except.py
    Enter something --> Python is exceptional!
    Done

     

    如果有多重异常情况,那么我们可以写多个except 来解决问题.

     

    2、try ... except...else语句

    现在我们来说说这个else语句。Python中有很多特殊的else用法,比如用于条件和循环。放到try语句中,其作用其实也差不多:就是当没有检测到异常的时候,则执行else语句。举个例子大家可能更明白些:

    >>> import syslog
    >>> try:
    ...     f = open("/root/test.py")
    ... except IOError,e:
    ...     syslog.syslog(syslog.LOG_ERR,"%s"%e)
    ... else:
    ...     syslog.syslog(syslog.LOG_INFO,"no exception caught ")
    ...
    >>> f.close()

    3、finally子句

    finally子句是无论是否检测到异常,都会执行的一段代码。我们可以丢掉except子句和else子句,单独使用try...finally,也可以配合except等使用。

    例如2.2的例子,如果出现其他异常,无法捕获,程序异常退出,那么文件 f 就没有被正常关闭。这不是我们所希望看到的结果,但是如果我们把f.close语句放到finally语句中,无论是否有异常,都会正常关闭这个文件,岂不是很妙!

    >>> import syslog
    >>> try:
    ...     f = open("/root/test.py")
    ... except IOError,e:
    ...     syslog.syslog(syslog.LOG_ERR,"%s"%e)
    ... else:
    ...     syslog.syslog(syslog.LOG_INFO,"no exception caught ")
    ... finally:
    >>>     f.close()

    ------------------------------------------------------------------------------------------------------- 

    Python是面向对象语言,所以程序抛出的异常也是类。常见的Python异常有以下几个

    python标准异常

    异常名称描述
    BaseException 所有异常的基类
    SystemExit 解释器请求退出
    KeyboardInterrupt 用户中断执行(通常是输入^C)
    Exception 常规错误的基类
    StopIteration 迭代器没有更多的值
    GeneratorExit 生成器(generator)发生异常来通知退出
    StandardError 所有的内建标准异常的基类
    ArithmeticError 所有数值计算错误的基类
    FloatingPointError 浮点计算错误
    OverflowError 数值运算超出最大限制
    ZeroDivisionError 除(或取模)零 (所有数据类型)
    AssertionError 断言语句失败
    AttributeError 对象没有这个属性
    EOFError 没有内建输入,到达EOF 标记
    EnvironmentError 操作系统错误的基类
    IOError 输入/输出操作失败
    OSError 操作系统错误
    WindowsError 系统调用失败
    ImportError 导入模块/对象失败
    LookupError 无效数据查询的基类
    IndexError 序列中没有此索引(index)
    KeyError 映射中没有这个键
    MemoryError 内存溢出错误(对于Python 解释器不是致命的)
    NameError 未声明/初始化对象 (没有属性)
    UnboundLocalError 访问未初始化的本地变量
    ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
    RuntimeError 一般的运行时错误
    NotImplementedError 尚未实现的方法
    SyntaxError Python 语法错误
    IndentationError 缩进错误
    TabError Tab 和空格混用
    SystemError 一般的解释器系统错误
    TypeError 对类型无效的操作
    ValueError 传入无效的参数
    UnicodeError Unicode 相关的错误
    UnicodeDecodeError Unicode 解码时的错误
    UnicodeEncodeError Unicode 编码时错误
    UnicodeTranslateError Unicode 转换时错误
    Warning 警告的基类
    DeprecationWarning 关于被弃用的特征的警告
    FutureWarning 关于构造将来语义会有改变的警告
    OverflowWarning 旧的关于自动提升为长整型(long)的警告
    PendingDeprecationWarning 关于特性将会被废弃的警告
    RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
    SyntaxWarning 可疑的语法的警告
    UserWarning 用户代码生成的警告

     

     

    Python官网异常类查询文档:

    https://docs.python.org/2/library/exceptions.html#bltin-exceptions

    http://www.runoob.com/python/python-exceptions.html

     

     

  • 相关阅读:
    重置 Mac 上的 NVRAM 或 PRAM
    为什么我的mac插入耳机耳机没有声音呢?
    Redis 实现安全队列
    设计模式之十三:适配器模式(Adapter)
    关于cocos2dx手游lua文件加密的解决方式
    Django中载入js和css文件
    CCNA 例题精选
    JNI/NDK开发指南(四)——字符串处理
    error when loading the sdk 发现了元素 d:skin 开头无效内容
    Webx学习(一)
  • 原文地址:https://www.cnblogs.com/wjoyxt/p/4548488.html
Copyright © 2011-2022 走看看