• Python错误与异常


     1 异常和错误 

    1.1 错误和异常 

    从软件方面来说,错误是语法或者逻辑上的,语法错误指示软件的结构上有错误,导致不能被解释器解释。当程序的语法正确后,剩下的就是逻辑错误了,逻辑错误可能是由于不完整或者不合法的输入所致。当Python检测到一个错误时,解释器就会指出当前流无法继续执行下去,这就出现了异常。

    对异常的描述是:它是因为程序出现了错误而在正常控制流以外采取的行为,这个行为又分为两个阶段:首先是引起异常发生的错误,然后是检测(和采取可能的措施)阶段。

    第一个阶段是发生在一个异常条件后发生的,只要检测到错误并且意识到异常条件,解释器就会触发一个异常。解释器通知当前控制流有错误发生。异常就是错误发生的信号,当前流被打断,用来处理这个错误并采取相应的操作。这就是第二阶段。

    对异常的处理发生在第二阶段,异常引发后,可以调用不同的操作,可以忽略错误,或是减轻问题的影响后设法继续执行,所有的这些操作都是代表一种继续,或是控制的分支。关键是程序员在错误发生时可以指示程序如何执行。 

    1.2 Python中的异常 

    1. NameError:尝试访问一个未声明的变量
    2. ZeroDivisionError:除数为0
    3. SyntaxError:Python解释器语法错误
    4. IndexError:请求的索引超出序列范围
    5. KeyError:请求一个不存在的字典关键字
    6. IOError:输入/输出错误
    7. AttributeError:尝试访问未知的对象属性 

    1.3 检测和处理异常 

    异常可以通过try语句来检测,任何在try语句块中的代码都会被检测,检测有无异常发生。

    try语句有两种主要的形式:try-except和try-finally语句。这两个语句是互斥的,只能使用其中的一个。一个try语句可以对应一个或多个except语句,但只能对应一个finally语句,或者是一个try-except-finally复合语句。 

    1.4 try-except语句 

    try-except语句(以及更复杂的形式)定义了进行异常监控的一段代码,并且提供了异常处理的机制。

    常见的语法格式如下:

    1 try:
    2     try_suite #监控这里的异常
    3 except Exception[, reason]:
    4     except_suite #异常处理的代码
    1 举例:
    2 >>> try:
    3 ...     f = open('bla', 'r')
    4 ... except IOError, e:
    5 ...     print 'could not open file', e
    6 ...
    7 could not open file [Errno 2] No such file or directory: 'bla'

    程序运行时,解释器尝试执行try里面的语句块,如果代码块执行后没有发生错误,执行流会忽略except语句继续执行,当except语句所指定的异常发生后,保存下错误的原因,控制流立即跳转到对应的处理器(try子句的剩余语句将被忽略)。 

    1.5 带有多个except的try语句 

    可以把多个except语句连接在一起,处理一个try块中可能发生的多种异常。如下:

    1 try
    2     try_suite #监控这里的异常
    3 except Exception1 [, reason]:
    4     suite_for_exception_Exception1
    5 except Exception2 [, reason]:
    6     suite_for_exception_Exception2 

    首先执行try子句,如果没有错误,忽略所有的except从句继续执行,如果发生异常,解释器将在这一串处理器(except子句)中查找匹配的异常,如果找到对应的处理器,执行流将跳转到这里。 

    1.5 处理多个异常的except语句 

    可以在一个except子句里处理多个异常,except语句在处理多个异常时要求异常被放在一个元组里:

    1 except (Exception1, Exception2) [, reason]:
    2     suite_for_Exception1_and_Exception2

    事实上except语句可以处理任意多个异常,前提只是他们放在一个元组里,如下:

    1 except (Exc1,[, Exc2 [, … ExcN]]) [, reason]:
    2     suite_for_exceptions_Excl_to_ExcN

     1.6 捕获所有异常 

    异常是遵循继承结构的,Exception是在最顶层。

    1 try:
    2     ;
    3 except Exception. e:
    4     #error occurred, etc.

    Python2.5,异常被迁移到了新式类上,启用了一个新的"所有的异常之母",这个类叫做BaseException,KeyboardInterrupt和SystemExit和Exception同级了。如果需要捕获所有的异常,格式如下:

    1 try:
    2     ;
    3 except BaseException, e:
    4     #error occurred, etc. 

    1.8 "异常参数" 

    异常也可以有参数,异常引发后会被传递给异常处理器。当异常被引发后参数是作为附加帮助信息传递给异常处理器的。标准内建异常提供至少一个参数,指示异常原因的一个字符串。添加异常参数的except扩展语法如下:

    1 except (Exception1, Exception2, …, ExceptionN), [, reason):
    2     suite_for_Exception1_to_ExceptionN_with_Argument

    异常参数自身组成一个元组,并存储为类实例(异常类的实例)的属性。

     1 #!/usr/bin/env python
     2 
     3 def safe_float(obj):
     4     'safa version of float()'
     5     try:
     6         retval = float(obj)
     7     except (ValueError, TypeError), diag:
     8         retval = str(diag)
     9     return retval
    10 
    11 def main():
    12     'handle all the data processing'
    13     log = open('cardlog.txt', 'w')
    14     try:
    15         ccfile = open('carddata.txt', 'r')
    16     except IOError, e:
    17         log.write('no txns this month
    ')    
    18         log.close()
    19         return
    20     txns = ccfile.readlines()
    21     ccfile.close()
    22     total = 0.00
    23     log.write('account log:
    ')
    24 
    25     for eachTxn in txns:
    26         result = safe_float(eachTxn)
    27         if isinstance(result, float):
    28             total += result
    29             log.write('data... processed
    ')
    30         else:
    31             log.write('ignord: %s' % result)
    32     print '$%.2f (new balance)' % (total)
    33     log.close()
    34 
    35 if __name__ == '__main__':
    36     main() 

    1.9 else子句 

    在try范围内没有异常被检测到时,执行else子句。在else范围中的任何代码执行前,在try范围中的所有代码必须完全成功。

    1 try:
    2     ;
    3 except Exception. e:
    4     #error occurred, etc.
    5 else:
    6

    1.11 finally子句 

    finally子句是无论异常是否发生,是否捕捉都会执行的一段代码。语法示例如下:

    1 try:
    2     ;
    3 except Exception. e:
    4     #error occurred, etc.
    5 else:
    6

    1.12 try-except-else-finally语句 

    综合所有不同的可以处理异常的语法样式如下:

     1 try:
     2     try_suite
     3 except Exception1:
     4     suite_for_Exception1
     5 except (Exception2, Exception3, Exception4):
     6     suite_for_Exception2_3_and_4
     7 except Exception5, Argument5:
     8     suit_for_Exception5_plus_argument
     9 except (Exception6, Exception7), Argument67:
    10     suit_for_Exception6_and_Exception7_plus_argument
    11 except:
    12     suit_for_all_other_exceptions
    13 else:
    14 no_exceptions_detected_suits
    15 finally:
    16     always_execute_suite 

    2 上下文管理 

    2.1 with语句 

    with语句的目的在于从流程图中把try、except和finally关键字和资源分配释放相关的代码统统去掉。基本用法如下:

    1 with context_expr [as var]:
    2     with_suite

    with仅能工作支持上下文管理协议的对象,下面是一些支持该协议的对象:

    file

    decimal.Context

    thread.LockType

    threading.Lock

    threading.RLock

    threading.Condition

    threading.Semaphore

    threading.BoundedSemaphore

    用file来进行举例:

    1 >>> with open('/etc/passwd', 'r') as f:
    2 ...     for eachLine in f:
    3 ...         #do stuff with eachLine of f... 

    无论在这一段代码的开始、中间或结束发生异常,会执行清除的代码,此时文件仍会被自动的关闭。 

    3 触发异常 

    raise语句用于触发异常,一般语法如下:

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

    第一个参数,SomeException,是触发异常的名字,如果有,必须是一个字符串、类或实例。

    第二个符号为可选的args(比如参数、值),来传给异常。可以是一个单独的对象也可以是一个对象的元组。当异常发生时,异常的参数总是作为一个元组传入。

    最后一个参数traceback是可选的,如果有的话,则是当异常触发时新生成的一个用于异常-正常化的跟踪记录对象。 

    4 断言 

    断言是一句必须等价于布尔真的判断,此外当异常发生也意味着表达式为假。如果断言成功不采取任何措施,否则触发AssertionError(断言错误)的异常,语法如下:

    assert expression [, arguments]

    举例:

    1 >>> assert 1==1
    2 >>> assert 1==2
    3 Traceback (most recent call last):
    4   File "<stdin>", line 1, in <module>
    5 AssertionError

    AssertionError(断言错误)的异常也可以使用try-except捕捉。

    附录:python内建异常

    异常名称

    描述

    BaseException

    所有异常的基类

    SystemExit

    Python解释器请求退出

    KeyboardInterrupt

    用户中断执行(通常是输入^C)

    Exception

    常规错误的基类

    StopIteration

    迭代器没有更多的值

    GeneratorExit

    生成器(generator)发生异常来通知退出

    StandardError

    所有的内建标准异常的基类

    ArithmeticError

    所有数值计算错误的基类

    FloatingPointError

    浮点计算错误

    OverflowError

    浮点运算超出最大限度

    ZeroDivisionError

    除(或取模)零(所有数据类型)

    AssertionError

    断言语句失败

    EOFError

    没有内建输入,到达EOF标记

    EnvironmentError

    操作系统错误的基类

    IOError

    输入/输出操作失败

    OSError

    操作系统错误

    WindowsError

    Windows系统调用失败

    ImportError

    导入模块/对象失败

    LookupError

    无效数据查询的基类

    IndexError

    序列中没有此索引

    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)的警告

    PendingDepressionWarning

    关于特征将会被废弃的警告

    RuntimeWarning

    可以的运行时行为的警告

    SyntaxWarning

    可疑的语法的警告

    UserWarning

    用户代码生成的警告

  • 相关阅读:
    javascript深入理解js闭包
    js数组与字符串的相互转换方法
    js 将json字符串转换为json对象的方法解析-转
    js、匿名函数、闭包、回调函数
    $.ajax()方法详解
    typeof操作符返回一个字符串,表示未经计算的操作数的类型。
    【转】mysql中文乱码的一点理解
    【转】国外程序员整理的 C++ 资源大全
    【转】CC++代码优化的27个建议
    一起学JUCE之HashMap
  • 原文地址:https://www.cnblogs.com/mrlayfolk/p/12024341.html
Copyright © 2020-2023  润新知