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\n')    
18         log.close()
19         return
20     txns = ccfile.readlines()
21     ccfile.close()
22     total = 0.00
23     log.write('account log:\n')
24 
25     for eachTxn in txns:
26         result = safe_float(eachTxn)
27         if isinstance(result, float):
28             total += result
29             log.write('data... processed\n')
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

用户代码生成的警告

posted @ 2019-12-11 18:25  zhengcixi  阅读(753)  评论(0编辑  收藏  举报
回到顶部