【Python基础】09、Python异

发布时间:2019-08-22 08:04:31编辑:auto阅读(421)

    一、python异常

    1、Python异常

    python运行时发生错误称作异常

    语法错误:软件的结构上有错误而导致不能被解释器解释或不能被编译器编译

    逻辑错误:由于不完整或不合法的输入所致,也可能是逻辑无法生成、计算或者输出结果需要的过程无法执行等

    Python异常是一个对象,表示错误或意外情况

    在Python检测到一个错误时,将触发一个异常

            Python可以通过异常传导机制传递一个异常对象,发出一个异常情况出现的信号

            程序员也可以在代码中手动触发异常

    Python异常也可以理解为:程序出现了错误而在正常控制流以外采取的行为

    第一阶段:解释器触发异常,此时当前程序流将被打断

    第二阶段:异常处理,如忽略非致命性错误、减轻错误带来的影响等


    2、异常的功用

    错误处理

          Python的默认处理停止程序,打印错误消息

          使用try语句处理异常并从异常中恢复

    事件通知

           用于发出有效状态信号

    特殊情况处理

           无法调整代码去处理的场景

    终止行为

           try/finally语句可确保执行必需的结束处理机制

    非常规控制流程

            异常是一种高级跳转(goto)机制


    3、检测和处理异常

    异常通过try语句来检测

           任何在try语句块里的代码都会被监测,以检查有无异常发生

    try语句主要有两种形式:

          try-except:检测和处理异常

                 可以有多个except

                 支持使用else子句处理没有探测异常的执行的代码

          try-finally:仅检查异常并做一些必要的清理工作

                 仅能有一个finally

    try语句的复合形式

           try-except-finally


    二、try语句

    1、try-except 语句

    定义了进行异常监控的一段代码,并且提供了处理异常的机制

    语法:

                try:

                       try_suite                           #触发异常

                except Exception[, reason]:    #Execption 异常类型, reason是自定义的变量捕获触发此错误的原因

                       except_suite       #触发错误后的操作        

    例子

    In [1]: xj
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-1-7e8eb9fe7515> in <module>()
    ----> 1 xj
    
    NameError: name 'xj' is not defined           #异常类型:触发此异常的原因
    
    In [2]: f1=open("/tmp/a.txt","r")
    ---------------------------------------------------------------------------
    IOError                                   Traceback (most recent call last)
    <ipython-input-2-0c148cacb126> in <module>()
    ----> 1 f1=open("/tmp/a.txt","r")
    
    IOError: [Errno 2] No such file or directory: '/tmp/a.txt'
    
    
    In [5]: try:
        open("/tmp/a.txt","r")
    except IOError,rs:
        print "Could not open file /tmp/a.txt",rs
       ...:     
    Could not open file /tmp/a.txt [Errno 2] No such file or directory: '/tmp/a.txt'

    try语句可以带多个except子句,还可以有一个可选的else子句,语法格式如下

          try:

                try_suite

          except Exception1[, reason]:

                suite_exception1

          except (Exception2, Exception3, …)[,reason]:           #一次捕获多个异常时要定义为元组

                suite_

                …

          except:                    #空except语句用于捕获一切异常

                suite_

         else:

               else_suite

    except分句个数没有限制,但else只能有一个

    没有异常发生时,else分句才会执行

    没有符合的except分句时,异常会向上传递到程序中的之前进入的try中或者到进程的顶层


    2、try-finally 语句

    无论异常是否发生,finally子句都会执行

           常用于定义必需进行的清理动作,如关闭文件或断开服务器连接 等

    finally中的所有代码执行完毕后会继续向上一层引发异常

    语法

    try:

          try_suite

    finally:

          finally_suite


    3、try-except except-else else-finally 语句

    语法:

    try:

         try_suite

    except Exception1:

         suite1_exception1

    except (Exception2, Exception3):

          suite23_exception23

    else:

          else_suite

    finally:

          finally_suite

    可以替换为在try-finally语句中嵌套try-except语句的形式


    4、自定义异常

    raise语句可显式触发异常

          raise [SomeException [, args [, traceback]]]

                SomeException: 可选,异常的类型(不能自定义,选一个已存在的异常类型),仅能使用字符串、类或实例

                args: 可选,以元组的形式传递给异常的参数

                traceback: 可选,异常触发时新生成的一个用于异常-正常化的跟踪记录,多用于重新引发异常时

    In [7]: def CrossProduct(seq1,seq2):
       ...:     if not seq1 or not seq2:
       ...:         raise ValueError,"Sequence argements must be non-empty"  
       ...:     return [(x1,x2) for x1 in seq1 for x2 in seq2]
       ...: 
       
       
    In [13]: l1=[1,2,3]
    
    In [14]: l2=[a,b,c]
    
    In [15]: l2=["a","b","c"]
    
    In [16]: CrossProduct(l1,l2)
    Out[16]: 
    [(1, 'a'),
     (1, 'b'),
     (1, 'c'),
     (2, 'a'),
     (2, 'b'),
     (2, 'c'),
     (3, 'a'),
     (3, 'b'),
     (3, 'c')]
     
     In [19]: CrossProduct(s1,s2)
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-19-98cbc2c76b89> in <module>()
    ----> 1 CrossProduct(s1,s2)
    
    <ipython-input-7-02dabd570938> in CrossProduct(seq1, seq2)
          1 def CrossProduct(seq1,seq2):
          2     if not seq1 or not seq2:
    ----> 3         raise ValueError,"Sequence argements must be non-empty"
          4     return [(x1,x2) for x1 in seq1 for x2 in seq2]
          5 
    
    ValueError: Sequence argements must be non-empty


    三、异常对象

    1、异常对象

    Python异常是内置的经典类Exception的子类的实例

          为了向后兼容,Python还允许使用字符串或任何经典类实例

          Python2.5之后,Exception是从BaseException继承的新式类

    Python自身引发的所有异常都是Exception的子类的实例

    大多的标准异常都是由StandardError派生的,其有3个抽象的子类

    ArithmeticError

          由于算术错误而引发的异常基类

          OverflowError, ZeroDivisionError, FloatingPointError

    LookupError

          容器在接收到一个无效键或索引时引发的异常的基类

          IndexError, KeyError

    EnvironmentError

         由于外部原因而导致的异常的基类

          IOError, OSError, WindowsError

    In [2]: type(Exception)
    Out[2]: type
    
    In [5]: type(BaseException)
    Out[5]: type


    2、标准异常类

    AssertionError

          断言语句失败

    AttributeError

           属性引用或赋值失效

    FloatingPointError

            浮点型运算失败

    IOError

           I/O操作失败

    ImportError

           import语句不能找到要导入的模块,或者不能找到该模块特别请求的名称

    IndentationError

             解析器遇到了一个由于错误的缩进而引发的语法错误

    IndexError

             用来索引序列的整数超出了范围

    KeyError

             用来索引映射的键不在映射中

    KeyboardInterrupt

            用户按了中断键(Ctrl+c, Ctrl+Break或Delete键)

    MemoryError

            运算耗尽内存

    NameError

            引用了一个不存在的变量名

    NotImplementedError

           由抽象基类引发的异常,用于指示一个具体的子类必须覆盖一个方法

    OSError

           由模块os中的函数引发的异常,用来指示平台相关的错误

    OverflowError

           整数运算的结果太大导致溢出

    SyntaxError

            语法错误

    SystemError

            Python本身或某些扩展模块中的内部错误

    TypeError

            对某对象执行了不支持的操作

    UnboundLocalError

             引用未绑定值的本地变量

    UnicodeError

              在Unicode的字符串之间进行转换时发生的错误

    ValueError

              应用于某个对象的操作或函数,这个对象具有正确的类型,但确有不适 当的值

    WindowsError

              模块os中的函数引发的异常,用来指示与Windows相关的错误

    ZeroDivisionError

               除数为0


    3、自定义异常类

    自定义异常和多重继承

           较有效的方法是从自定义异常类和标准异常类进行多重继承,例 如

          class CustomAttributeError(CustomException, AttributeError): 

                pass

    标准库中使用的其它异常

           Python标准库中的许多模块都定义了自己的异常类,如socket中的socket.error

                    等同于自定义的异常类


    4、assert语句

    assert语句用于在程序中引入调试代码

       assert condition[, expression]

             如果condition条件满足,则assert不做任何操作

             如果condition条件不满足,则assert使用expression作为参数实例化AssertionError并引发结果

    注意:

           如果运行Python时使用了-O优化选项,则assert将是一个空操作:编译器不为assert语句生成代码

           运行Python时不使用-O选项,则__debug__内置变量为True, 否则其值为False


    assert语句相当于下面的代码

    if __debug__:

           if not condition:

                  raise AssertionError, <expression>

    In [14]: assert 1==1
    
    In [15]: assert 1==2
    ---------------------------------------------------------------------------
    AssertionError                            Traceback (most recent call last)
    <ipython-input-15-a174714cc486> in <module>()
    ----> 1 assert 1==2
    
    AssertionError: 
    
    
    In [17]: assert 1==2,"sb"
    ---------------------------------------------------------------------------
    AssertionError                            Traceback (most recent call last)
    <ipython-input-17-ad988d3359bb> in <module>()
    ----> 1 assert 1==2,"sb"
    
    AssertionError: sb


    四、python执行环境

    1、python解释器环境与选项

    python [options] [-c cmd| filename | - ] [args]

    wKiom1gRwWCzh4PwAAE6fmRrKLc315.png

    python解释器环境变量

    wKioL1gRwe6Dl-fmAAECB4Zgye4663.png


    五、Python代码的测试、调试与探查

    1、Python文档字符串

           如果函数、类或模块的第一行是一个字符串,这个字符串就称为文档字符串(docstrings)

    内置函数help()或对象的默认方法__doc__可以显示这些文档字符串

    In [34]: def Sum(num1,num2):
       ....:     '''the sumary of num1 and num2.
       ....:     >>> Sum(2,5)
       ....:     7
       ....:     >>> Sum(12,77)
       ....:     89
       ....:     '''
       ....:     return num1+num2
       ....: 
       
    In [45]: Sum.__doc__
    Out[45]: 'the sumary of num1 and num2.\n    >>> Sum(2,5)\n    7\n    >>> Sum(12,77)\n    89\n    '
    
    In [46]: help(Sum)
    
    Help on function Sum in module __main__:
    
    Sum(num1, num2)
        the sumary of num1 and num2.
        >>> Sum(2,5)
        7
        >>> Sum(12,77)
        89
    (END)

    2、doctest模块

           doctest模块允许在文档字符串内嵌入注释以显示各种语句的期望行为,尤其是函数和方法的结果

                    此处的文档字符串看起来如同一个交互式shell会话

                    可用于测试文档是否与程序主体保持同步,或基于文档对程序本 身做测试

    wKioL1gRzOWzl693AADScE75Olg477.png

    如果文档字串中的结果与预期结果不一致,测试会显示出错的结果信息


    创建可自测试的模块

    在模块的尾部添加如下代码即可

    if __name__ == ‘__main__’:

         import doctest

        doctest.testmod()

    此类模块在python解释器中直接运行时即能进行自我测试


    unittest





关键字