“人无完人,金无足赤”,bug似乎会伴随程序员的一生,对于不遂我们意的事物,并不一定都需要一一消灭他们,就像程序中的某些异常一样,我们也可以选择一种更加和谐的方式来处理异常。
异常的引发原因
异常的引发可能有很多的原因,对于下面的这些异常我们应该是捕获他并给用户“友好”的提示,“别让用户看到异常,因为他们不关心这个,他们在乎的是怎么样正确的使用你的软件完成他们的工作”:
- 用户的错误输入
- 依赖的某些系统本身无法控制的资源
下面来看一个例子:
__author__ = 'anys'
fp = open('test.log', 'r')
print fp.readall()
fp.close()
打开当前目录下名为”test.log”的文件,打印从该文件中读入的全部数据,然后关闭文件。我们运行上面的这几行代码。运行结果:
在打开文件时发生了错误,原因是:“No such file or directory: ‘test.log’”。由于依赖的文件不存在而导致错误的发生,甚至应用程序的异常终止,这是不合理的。下面在看看一种和谐的方式:
__author__ = 'anys'
try:
fp = open('test.log', 'r')
print fp.readall()
fp.close()
except IOError as e:
print 'error when open file,error message:%s' % e.message
完善后的运行结果:
测试和捕获异常
python中对异常的处理语句为:
try:
statement_block_need_check
except IOError as e:
do_something()
try用于测试statement_block_need_check是否发生异常,如果发生异常将被except捕获,会进行异常的匹配,上例的except只匹配IOError异常
异常的种类
python的异常有很多种类,为了方便异常的捕获,定义了所有异常的基类BaseException,在BaseException之下再有其他的类,详情参照下图(图片来源,非常感谢):
捕获多类异常
一个被测试的语句块可能包含多个语句,虽然这是不提倡的,一个语句尚且可能引发多种类型的异常,更何况多个语句了,当被测试的语句块可能引发多种类型异常时我们使用如下的形式来捕获:
try:
do_something()
except IOError as e:
do_something()
except OSError as e:
pass
except KeyboardInterrupt as e:
pass
else:
pass
当异常引发时,会逐个except匹配,如果不能匹配任何一个异常将继续网上引发,直到该异常被捕获,如果一直不被捕获将会出现应用程序异常。如果为引发异常将会执行else语句块的内容。还可以配合:
finally:
pass
无论如何都执行的语句块,如果finally语句块中使用了一些变量,切记一定要保证该变量在使用前已经定义。
引发自己的异常
某些时候,所以得标准异常可能都无法清晰的描述我们的异常,我们就需要定义自己的异常类型,定义异常类型建议继承自Exception。类似:
class NameErrorException(Exception):
pass
当然可以在类里面做一些自定义的操作、或者设置一些自定义的属性,定义异常后在需要的地方使用raise来引发异常
raise NameErrorException()
如果有更多更好的内容,还望多多交流,邮箱:cug_heshun@sina.com