Python错误、调试和测试

一、错误处理
高级语言都内置了一套“try…..except…..finally”错误处理机制。
①try机制

try:
    r=12/0
    print ('result:',r)
except ZeroDivisionEror,e:   #e可用其他字符代替,表示一个变量,在这里e=='inter division or modulo by zero'
    print 'except:',e
finally:#finnally可有可无,无论代码是否有错误都会执行
    print 'finally....'
print 'end'

上面代码在计算12/0时会产生一个除法运算错误:
except: integer division or modulo by zero
finally….
end
当发生错误时不再执行print ‘result:’,r
若没有错误发生,except语句不会执行;另外错误会有不同种类,所以可以有多个不同的except语句;如果没有错误发生,可以在except语句后加一个else语句,没有错误发生就可以执行该语句。另:所有的错误类型都继承自BaseException,所以可以用一个expect StandardError,e: 语句,省去用多个except语句去捕获错误。
使用try….expect 可以跨越多层调用,调用函数,函数嵌套无论在哪一层出错都可以捕获到比如下例:

    def foo(s)
        return 10 / int(s)
    def bar(s):
        return foo(s) * 2
    def main():
    try:
        bar('0')
    except StandardError, e:
        print 'Error!'
    finally:
        print 'finally...'
    main()

输出:

    Error integer division or modulo by zero

可见错误出现在foo()函数中,在函数调用中main()函数仍可以捕获到
②调用堆栈
如果错误为被找到,则会打印错误信息

  def f1(s):
      return 12/int(s)
  def f2(s):
      return f1(s)*2
  def main():
      f2('0')
  main()    

执行:结果如下

  Traceback (most recent call last):
  File "F:/python 代码/错误处理.py", line 7, in <module>
    main()
  File "F:/python 代码/错误处理.py", line 6, in main
    f2('0')
  File "F:/python 代码/错误处理.py", line 4, in f2
    return f1(s)*2
  File "F:/python 代码/错误处理.py", line 2, in f1
    return 12/int(s)
ZeroDivisionError: integer division or modulo by zero

可以看出,出现错误的地方为:

File "F:/python 代码/错误处理.py", line 2, in f1
return 12/int(s)

③记录错误
python内置的logging模块可以记录错误,把错误堆栈打印出来,同时让程序继续执行下去。

        import logging    #先导入
        def f1(s):
            return 12/int(s)
        def f2(s):
            return f1(s)*2
        def main():
        try:
            f2('0')
        except StandardError,e:   #增加的步骤
            logging.exception(e)
        main()
        print('End') 

于上个代码相比导入import,使用try…except。虽然同样出错,但打印完错误信息后会继续执行,并正常退出,执行代码如下:

ERROR:root:integer division or modulo by zero
Traceback (most recent call last):
  File "F:/python 代码/错误处理.py", line 8, in main
    f2('0')
  File "F:/python 代码/错误处理.py", line 5, in f2
    return f1(s)*2
  File "F:/python 代码/错误处理.py", line 3, in f1
    return 12/int(s)
ZeroDivisionError: integer division or modulo by zero
End

错误是一个class,例如python的内置函数:ValueError(),StandardError()…..或者我们自己定义一个错误类(必要的时候),但需要选择好继承关系例如:FooError(StandardError)…所以我们捕获到的错误就是类的一个实例。
我们可以根据需要,选择或定义一个错误类,用raise语句抛出错误。

def f3(s):
    n=int(s)
    if n==0:
        raise StandardError('invalid value: %s' % s)
    return 12/0
f3('0')

执行如下:

Traceback (most recent call last):
  File "F:/python 代码/错误处理.py", line 21, in <module>
    f3('0')
  File "F:/python 代码/错误处理.py", line 19, in f3
    raise StandardError('invalid value: %s' % s)
StandardError: invalid value: 0

打印完错误信息且程序继续执行。

另一种非常常见的错误处理方式:

def foo1(s):
    n = int(s)
    return 10 / n
def bar1(s):
    try:
        return foo1(s) * 2
    except StandardError, e:
        print 'Error!'
        raise    

def main1():
    bar1('0')

main1()

执行结果如下:

Error!

Traceback (most recent call last):
  File "F:/python 代码/错误处理.py", line 30, in <module>
    main1()
  File "F:/python 代码/错误处理.py", line 28, in main1
    bar1('0')
  File "F:/python 代码/错误处理.py", line 22, in bar1
    return foo1(s) * 2
  File "F:/python 代码/错误处理.py", line 19, in foo1
    return 10 / n
ZeroDivisionError: integer division or modulo by zero

可见,编辑器已经知道了有错误,而且又把错误通过raise抛出便于管理者尽快找出错误原因!若无raise则只输出“Error”!

二、调试
logging
与assert判断或print打印错误相比,logging不会抛出错误

import logging

s='0'
n=int(s)
logging.info('n=%d' %n)     #logging.info()可以输出一段文本,且其需放在可能会出错误的语句之前
print 10/n

运行后只会输出ZeroDivisionError,这跟logging制定记录的错误信息级别有关,有debug,info,warning,error等几个级别,例如在import logging后导入:

import logging
logging.basicConfig(level=logging.INFO)

会输出

INFO:root:n = 0
Traceback (most recent call last):
  File "err.py", line 8, in <module>
    print 10 / n
ZeroDivisionError: integer division or modulo by zero

指定不同的级别就会输出不同的信息

======================================
学艺不精、未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值