异常处理机制:
try……except……else……finally…… 当我们认为某些代码可能会出错时,就可以用try来运行这段代码, 如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后, 如果没有错误发生,可以在except语句块后面加一个else,当没有错误发生时,会自动执行else语句。 如果有finally语句块,则执行finally语句块,至此,执行完毕。 当发生了不同类型的错误时,应该由不同的except语句块处理,可以用多个except来捕获不同类型的错误。 如果没有错误发生时,可以在except语句块后面加上一个else,当没有错误发生时,会自动执行else语句。 python的错误其实也是class,所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。 常见错误类型和继承关系:https://docs.python.org/3/library/exceptions.html#exception-hierarchy 使用try……except捕获错误还有一个巨大的好处,就是可以跨越多层调用,这样,就不需要在每个可能出错的地方去捕获错误,只要在合适的层次去捕获错误就可以了,大大减少了写try……except……finally的麻烦。 如果错误没有被捕获,它就会一直往上抛,最后被python解释器捕获,打印一个错误信息,然后程序退出。出错的时候,一定要分析错误的调用栈信息,才能定位错误的位置。 python内置的logging模块可以非常容易地记录错误信息。通过配置,logging可以把错误记录到日志文件里,方便事后排查。 抛出错误:raise。因为错误是class,捕获一个错误就是捕获到该class的一个实例,因此错误并不是凭空产生的,而是有意创建并抛出的。python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。 如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise语句抛出一个错误实例。 只有在必要的时候才定义我们自己的错误类型,如果可以选择python已有的内置的错误类型,尽量使用python内置的错误类型。 对于错误可以有两种处理方法: 1、捕获异常,进行处理。 2、将错误往上抛,让上层去处理。有时候捕获了错误,但不知如何处理该错误,此时,最好的方法就是继续往上抛,让顶层调用者去处理。 raise语句如果不带参数,就会把当前错误原样抛出,此外,在except中raise一个Error,还可以把一种类型的错误转化为另一种类型。只要是合理的转换逻辑就可以了,但是,决不应该把一个IOError转换为毫不相干的ValueError。 调试:方法有 1、简单粗暴,用print()把可能有问题的变量打印出来看看。但是用print()最大的坏处就是将来还得删除它,否则运行结果中也会包含很多垃圾信息。 2、断言,assert(),凡是用print()来辅助查看的地方,都可以用断言(assert)来代替。 assert expression1, expression2 当expression1为假时,这个程序退出,并输出一条错误信息expression2。若expression1为真,则继续执行后面的语句。 如果程序中到处充斥着assert,和print()相比好不到哪去,启动python解释器时可以用-O参数来关闭assert。关闭后,可以把所有的assert语句当成pass来看。 如:python -O xxx.py 3、logging:logging不会抛出错误,而且可以输出到文件。 使用时,需要: import logging logging.basicConfig(level=logging.INFO) 然后在代码中使用logging.info("xxxxx")输出log信息。 logging允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。 同理,指定level=WARNING后,debug和info就不起作用了。这样一来,就可以放心的输出不同级别的信息,也不用删除,最后统一控制输出那个级别的信息。 logging的另一个好处就是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。 4、pdb 启动python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。 以参数-m pdb启动,如:python -m pdb xxx.py 启动后,输入命令 l:查看代码, n:单步执行代码 p 变量名:查看变量的值 q:结束调试,退出程序 5、pdb.set_trace(): 这个方法也是用pdb,但是不需要单步执行,但需要import pdb,然后在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点。 运行代码,程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行。 这种方式比直接启动pdb单步调试效率要高。 6、IDE 如果要比较爽的设置断点、单步执行,就需要一个支持调试功能的IDE,目前比较好的python IDE有: visual studio code:需要安装python插件 pycharm eclipse加上pydev插件也可以调试python程序 小结:虽然调试方法众多,但是,最后会发现,logging才是终极武器。