前言
Python的异常处理能力非常强大,但是用不好也会带来负面的影响。我平时写程序的过程中也喜欢使用异常,虽然采取防御性的方式编码会更好,但是交给异常处理会起到偷懒作用。偶尔会想想异常处理会对性能造成多大的影响,于是今天就试着测试了一下。
Python异常(谷歌开源风格指南)
提示:
允许使用异常,但必须小心。
定义:
异常是一种跳出代码块的正常控制流来处理错误或者其它异常条件的方式。
优点:
正常操作代码的控制流不会和错误处理代码混在一起。当某种条件发生时,它也允许控制流跳过多个框架。例如,一步跳出N个嵌套的函数,而不必继续执行错误的代码。
缺点:
可能会导致让人困惑的控制流。调用库时容易错过错误情况。
结论:
<强>异常必须遵守特定条件:强>
像这样触发异常:<代码>提高MyException(“错误信息”)> 代码或者<代码>提高MyException> 代码。不要使用两个参数的形式(<代码>提高MyException,“错误信息”> 代码)或者过时的字符串异常(<代码>提高“错误信息”代码>)。
模块或包应该定义自己的特定域的异常基类,这个基类应该从内建的异常类继承。模块的异常基类应该叫做“错误”
类错误(异常): 通过
永远不要使用<代码> 代码>:除了语句来捕获所有异常,也不要捕获代码>或<代码>例外者<代码> StandardError> 代码,除非你打算重新触发该异常,或者你已经在当前线程的最外层(记得还是要打印一条错误消息)。在异常这方面,Python非常宽容,除了代码>:<代码>真的会捕获包括Python语法错误在内的任何错误。使用除了:很容易隐藏真正的错误。
尽量减少try/除了块中的代码量。试块的体积越大,期望之外的异常就越容易被触发。这种情况下,try/除了块将隐藏真正的错误。
使用最后子句来执行那些无论试块中有没有异常都应该被执行的代码。这对于清理资源常常很有用,例如关闭文件。
当捕获异常时,使用,而不要用逗号。例如
试一试: 提高错误 除了错误的错误: 通过
设计实验方式
采取比较简单直观的对照实验。
先定义一个装饰器,用来计算每个函数执行所需时间:
def计时器(函数): 导入的时间 def包装器(* args, * * kwargs): 开始时间=time.time () f=func (* args, * * kwargs) endTime=time.time () 娱乐=endTime -开始时间 打印”执行函数% s使用了% f秒”% (getattr(函数、“__name__”),娱乐) 返回f 返回包装
然后用该装饰器装饰测试的函数即可。
再定义一个叫do_something的函数,这个函数中就做一件事,把1赋值给变量。在每个测试函数中,都会调用这个函数1000000次。
do_something:
def do_something (): 一个=1
我根据情况设计了不同的测试组:
测试组1(直接执行耗时操作):
@timer def test1 (): 在xrange (1000000): _ do_something ()
测试组2(耗时操作放在尝试中执行,不抛出错误):
@timer def test2 (): 试一试: 在xrange (1000000): _ do_something () 除了例外: do_something () 其他: 通过 最后: 通过
测试组3(试着放耗时操作中,尝试每一次操作,不抛出错误):
@timer def test3 (): 在xrange (1000000): _ 试一试: do_something () 除了例外: do_something () 其他: 通过 最后: 通过
测试组4(试着放耗时操作中,尝试每一次操作并进行异常处理(捕捉抛出的特定异常)):
@timer def test4 (): 0=0 在xrange (1000000): _ 试一试: 如果零==0: 提高ZeroDivisionError 除了ZeroDivisionError: do_something () 其他: 通过 最后: 通过Python异常对代码运行性能的影响实例解析