个性化阅读
专注于IT技术分析

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版中引入。

程序员通常将断言放在函数的开头来检查有效的输入,并在函数调用之后检查有效的输出。

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/python

try:
   fh = open("testfile", "w")
   fh.write("Test文件,用于异常处理")
except IOError:
   print "Error: 不能打开文件或读取数据"
else:
   print "成功写入数据到文件!"
   fh.close()

本例尝试打开一个没有写权限的文件,因此会引发异常

#!/usr/bin/python

try:
   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/python

try:
   fh = open("testfile", "w")
   fh.write("Test文件,用于异常处理")
finally:
   print "Error: 不能打开文件或读取数据"

如果你没有权限以写模式打开文件,那么将产生以下结果

Error: can't find file or read data

同样的例子可以写得更干净,如下所示

#!/usr/bin/python

try:
   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
赞(0)
未经允许不得转载:srcmini » python异常处理和断言 – Python入门开发教程

评论 抢沙发

评论前必须登录!