python异常处理和断言 – Python入门开发教程

上一章Python教程请查看:python文件IO操作
Python提供了两个非常重要的特性来处理Python程序中的任何意外错误,并在其中添加调试功能:

  • 异常处理——这将在本教程中讨论,下面是Python中可用的标准异常列表:标准异常。
  • 断言——这将在Python教程中的断言中讨论。
下面是标准异常清单:
编号 异常名称 & 说明
1 Exception 所有异常的基类
2 StopIteration 当迭代器的next()方法不指向任何对象时引发。
3 SystemExit 由sys.exit()函数引发。
4 StandardError 除了StopIteration和SystemExit之外的所有内置异常的基类。
5 ArithmeticError 用于数值计算中出现的所有错误的基类。
6 OverflowError 当计算超过数值类型的最大限制时引发。
7 FloatingPointError 当浮点运算失败时引发。
8 ZeroDivisionError 当对所有数值类型进行除法或除0时引发。
9 AssertionError 在断言语句失败时引发。
10 AttributeError 在属性引用或赋值失败时引发。
11 EOFError 当没有来自raw_input()或input()函数的输入且到达文件末尾时引发。
12 ImportError 当导入语句失败时引发。
13 KeyboardInterrupt 当用户中断程序执行时触发,通常通过按Ctrl+c。
14 LookupError 所有查找错误的基类。
15 IndexError 在序列中找不到索引时引发。
16 KeyError 在字典中找不到指定的键时引发。
17 NameError 在本地或全局命名空间中找不到标识符时引发。
18 UnboundLocalError 试图访问函数或方法中的局部变量,但没有为其赋值时引发。
19 EnvironmentError 用于Python环境之外发生的所有异常的基类。
20 IOError 当输入/输出操作失败时引发,例如尝试打开不存在的文件时打印语句或open()函数。
21 IOError 与操作系统相关的错误。
22 SyntaxError 当Python语法出现错误时引发。
23 IndentationError 未正确指定缩进时引发。
24 SystemError 当解释器发现内部问题,但遇到此错误时,Python解释器不退出。
25 SystemExit 使用sys.exit()函数退出Python解释器时引发。如果不在代码中处理,则导致解释器退出。
26 TypeError 尝试对指定数据类型无效的操作或函数时引发。
27 ValueError 当数据类型的内置函数具有有效的参数类型,但参数具有指定的无效值时引发。
28 RuntimeError 当生成的错误不属于任何类别时引发。
29 NotImplementedError 当需要在继承类中实现的抽象方法实际上没有实现时引发。
一、Python中的断言断言是一种健康检查,你可以在完成对程序的测试后打开或关闭它。
思考断言最简单的方法是将其比作一个raise-if语句(或者更准确地说,一个raise-if-not语句),对表达式进行测试,如果结果为false,则引发异常。
断言由assert语句执行,这是Python最新的关键字,在1.5版中引入。
【python异常处理和断言 – Python入门开发教程】程序员通常将断言放在函数的开头来检查有效的输入,并在函数调用之后检查有效的输出。
1、断言语句
当遇到assert语句时,Python会对相应的表达式求值,希望结果为,。如果表达式为false, Python将抛出AssertionError异常。
断言的语法是-
assert Expression[, Arguments]

如果断言失败,Python使用ArgumentExpression作为AssertionError的参数。AssertionError异常可以像使用try-except语句处理任何其他异常一样被捕获和处理,但是如果不处理,它们将终止程序并产生回溯。
这是一个把温度从开氏度转换成华氏度的函数,由于0开氏度是最冷的温度,当温度为负时,函数就会停止工作
#!/usr/bin/python def KelvinToFahrenheit(Temperature): assert (Temperature >= 0)," 比绝对零度还要冷!" return ((Temperature-273)*1.8)+32 print KelvinToFahrenheit(273) print int(KelvinToFahrenheit(505.78)) print KelvinToFahrenheit(-5)

二、什么是异常?异常是一个事件,它发生在程序执行过程中,打乱了程序指令的正常流程。通常当Python脚本遇到它无法处理的情况时,它会引发异常,异常是表示错误的Python对象。
当Python脚本引发异常时,它必须立即处理异常,否则将终止并退出。
三、处理异常如果你有一些可能引发异常的可疑代码,你可以通过将可疑代码放在try:块中来保护你的程序,在try:块之后,包含一个except:语句,然后是一个代码块,它尽可能优雅地处理问题。
下面是try…except…else的简单语法
try: 你的操作; ...................... except ExceptionI: 如果发生异常ExceptionI,则执行该语句块. except ExceptionII: 如果发生异常ExceptionII,则执行该语句块. ...................... else: 如果没有则执行该语句块.

这里有一些关于上述语法的要点:
  • 一个try语句可以有多个except语句,当try块包含可能抛出不同类型异常的语句时会很有用。
  • 你还可以提供一个通用的except子句,用于处理任何异常。
  • 在except子句之后,你可以加上else子句,如果try:块中的代码没有引发异常,则执行else块中的代码。
  • else块是不需要try。
这个例子打开一个文件,在文件中写入内容,然后优雅地输出,因为根本没有问题
#!/usr/bin/pythontry: fh = open("testfile", "w") fh.write("Test文件,用于异常处理") except IOError: print "Error: 不能打开文件或读取数据" else: print "成功写入数据到文件!" fh.close()

本例尝试打开一个没有写权限的文件,因此会引发异常
#!/usr/bin/pythontry: fh = open("testfile", "r") fh.write("Test文件,用于异常处理") except IOError: print "Error: 不能打开文件或读取数据" else: print "成功写入数据到文件!"

四、没有异常的except子句你也可以使用except语句,但没有如下定义的异常
try: 你的操作; ...................... except: 有任何异常则执行. ...................... else: 如果没有则执行该语句块.

这种try-except语句捕获发生的所有异常,但是使用这种try-except语句并不被认为是一种好的编程实践,因为它捕获了所有的异常,但并不能让程序员确定可能发生的问题的根本原因。
五、包含多个异常的except子句你还可以使用相同的except语句来处理多个异常,如下所示
try: 你的操作; ...................... except(Exception1[, Exception2[,...ExceptionN]]]): 如果给定异常列表中有任何异常,则执行此块. ...................... else: 如果没有则执行该语句块.

六、try-finally子句你可以使用finally: block和try: block,finally块是放置必须执行的任何代码的地方,不管try块是否引发异常,try-finally的语法是这样的:
try: 你的操作; ...................... 由于任何异常,这可能被跳过. finally: 一定被执行. ......................

不能同时使用else子句和finally子句。
#!/usr/bin/pythontry: fh = open("testfile", "w") fh.write("Test文件,用于异常处理") finally: print "Error: 不能打开文件或读取数据"

如果你没有权限以写模式打开文件,那么将产生以下结果
Error: can't find file or read data

同样的例子可以写得更干净,如下所示
#!/usr/bin/pythontry: fh = open("testfile", "w") try: fh.write("Test文件,用于异常处理") finally: print "关闭文件" fh.close() except IOError: print "Error: 不能打开文件或读取数据"

当在try块中抛出异常时,执行立即传递到finally块。在finally块中的所有语句执行完之后,异常再次被引发,如果出现在try-except语句的上一层,则在except语句中进行处理。
七、异常参数异常可以有一个参数,该参数是提供有关问题的附加信息的值,参数的内容因异常而异,通过在except子句中提供如下变量来捕获异常的参数:
try: 你的操作; ...................... except ExceptionType, Argument: 可以在这里打印参数Argument...

如果编写代码来处理单个异常,那么可以在except语句中在异常的名称后面加上一个变量。如果要捕获多个异常,可以在异常的元组后面加上一个变量。
此变量接收异常的值,这些值主要包含异常的原因。变量可以以元组的形式接收单个值或多个值,这个元组通常包含错误字符串、错误号和错误位置。
下面是一个异常的例子:
#!/usr/bin/python# 定义一个函数. def temp_convert(var): try: return int(var) except ValueError, Argument: print "参数不包含数字\n", Argument# 调用函数. temp_convert("xyz");

八、抛出异常可以通过使用raise语句以多种方式抛出异常,raise语句的一般语法如下所示。
raise [Exception [, args [, traceback]]]

在这里Exception是异常的类型(例如NameError),而argument是Exception参数的值,参数是可选的,如果没有提供,则异常参数为None。
最后一个参数traceback也是可选的(在实践中很少使用),如果存在它是用于异常的traceback对象。
异常可以是字符串、类或对象,Python核心提出的大多数异常都是类,其参数是类的实例,定义新的异常是很容易的,可以这样做
def functionName( level ): if level < 1: raise "无效level!", level # 如果抛出了该异常,下面的代码不会再执行

注意:了捕获异常,“except”子句必须引用类对象或简单字符串抛出的同一个异常。例如为了捕获上面的异常,我们必须像下面这样编写except子句
try: 业务逻辑... except "无效level!": 异常处理... else: 这里是其余代码...

九、用户自定义异常Python还允许你通过从标准的内置异常派生类来创建自己的异常。
下面是一个与RuntimeError相关的示例,这里创建了一个从RuntimeError派生的类,当你需要在捕获异常时显示更具体的信息时,这非常有用。
在try块中用户定义的异常被引发并在except块中捕获,变量e用于创建类Networkerror的实例。
class Networkerror(RuntimeError): def __init__(self, arg): self.args = arg

因此一旦你定义了上述类,就可以按照以下方式引发异常:
try: raise Networkerror("无效的hostname") except Networkerror,e: print e.args

    推荐阅读