Python学习笔记7

Python学习笔记–7.Exceptions and debugging

MrZigZag @ Peking Universty

2015-07-20


1.异常处理

高级语言一般面对异常都会内置一套try-catch-finally机制。Python相应的机制是try-except-finally

当我们认为某些代码可能会出错时,可以用try块来运行这段代码,运行出错时会立即跳转到except块,执行完之后跳出,如果有finally块则执行,否则中断程序。

错误有许多种,例如ValueErrorZeroDivisionError等,面对不同的错误应该由不同的except块来处理。Python的错误都是类,继承自BaseException,因此使用catch块时应注意范围,基类应该放在后面,否则会出现后面的错误被前面的处理这种情况。(反正这个在Java会报错,Python应该不会。)

如果没用try-except-finally机制,则出现错误时会根据堆栈逐步上传,直到__main__

raise语句抛出错误,一般只有在必要的时候才会定义自己的错误类型。尽量选择Python内置的错误类型。

class FooError(StandardError):
    pass

def foo(s):
    n = (int)s
    if n == 0:
        raise FooError('invalid value:%s' % s)
    return 10 / n

raise语句如果不带参数,会把当前的错误原样抛出,方便上一层进行处理。在except块中,还可以raise一个error然后将一种类型的错误转换成另一种错误。

logging,记录错误堆栈并让程序继续执行下去。利用logging模块可以非常容易记录错误信息。

import logging
def foo(s):
    return 10 / int(s)
def bar(s):
    return foo(s) * 2

def main():
    try:
        bar('0')
    except StandardError, e:
        logging.exception(e)

main()
print 'END'

会出错,但是程序会打印错误信息,之后继续执行。

通过配置,还可以将logging写入到文件里,方便时候排查。

2.调试

断言assert语句判断是否成立,如果断言失败就会抛出AssertError并且终止程序。

def foo(s):
    n = (int)s
    assert n != 0, 'n is zero!'
    return 10 / n

启动Python解释器时可以用-O参数来关闭assert。之后解释器会将assert语句当做pass来看。

logging,与assert相比,logging不会抛出错误,还可以输出到文件,而且logging还可以根据不同的配置指定记录信息的级别,有DEBUG, INFO, WARNING, ERROR四个级别,指定级别时,低级的级别就会失效。

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

logging.info('Test Logging')

PDB,利用pdb可以逐行执行,也可以调用pdb.set_trace()设置断点。