Bug:程序编写有问题造成的错误,称之为Bug. debug:调试
注意:bug是程序本身有问题、有缺陷、系统漏洞
异常:完全无法在程序运行中预测的错误,例如写入文件的时候,磁盘满了,写不进去了,或者从网络抓取数据时,网络突然断掉了
try ……except……finally……
某些代码可能会出错,那么放置在try语句块中,如果出错,则try中的后续语句块不执行,而是跳转到Except语句块,执行完except语句块,如果有finally,则执行finally,至此完毕
无论如何,都会执行finally语句,还可以在except语句后添加else语句
python所有的错误都是从BaseException类继承派生来的
UnicodeError是ValueError的子类
调用栈
如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息
注:出错的时候,一定要分析错误的调用栈信息,才能定位错误的位置
记录错误
Python内置的logging模块可以非常容易地记录错误信息
通过配置,logging还可以把错误记录到日志文件里,方便事后排查
1 #记录错误logging 2 #err_logging.py 3 import logging 4 def foo(s): 5 return 10/int(s) 6 7 def bar(s): 8 return foo(s)*2 9 10 def main(): 11 try: 12 bar('0') 13 except Exception as e: 14 logging.exception(e) 15 16 main() 17 print('END')
结论:可以看到,同样是出错,但程序打印完错误信息后会继续执行,并正常退出。
抛出错误
因为错误是class,捕获一个错误就是捕获到该class的一个实例。Python的内置函数会抛出很多类型的错误
只有在必要的时候才定义我们自己的错误类型。尽量使用Python内置的错误类型(如ValueError,TypeError)
1 #抛出错误的另一种处理方式 2 3 def foo(s): 4 n=int(s) 5 if n==0: 6 raise ValueError("invalid value:%s" % s) 7 return 10/n 8 9 def bar(): 10 try: 11 print('i am a good boy') #这句执行了 12 foo('s') 13 #执行这句时报错了,跳到except语句块,所以后面的语句就没有执行了 14 print('i am a good girl') #这句没有执行 15 except ValueError as e: 16 print('ValueError') 17 raise 18 19 bar()
运行结果:
结论:1、可以看到程序执行到哪一句停止往下执行了
2、except语句块中raise后面没有任何参数,这种情况下,就会把当前错误原样抛出
1 def foo(s): 2 n=int(s) 3 if n==0: 4 raise ValueError("invalid value:%s" % s) 5 return 10/n 6 7 def bar(): 8 try: 9 print('i am a good boy') #这句执行了 10 foo('s') 11 #执行这句时报错了,跳到except语句块,所以后面的语句就没有执行了 12 print('i am a good girl') #这句没有执行 13 except ValueError as e: 14 print('ValueError') 15 raise (" ok") 16 #在raise后面自定义添了这句 17 18 bar()
运行结果:
在前面,看到了BaseException这个词,不太明白,这自定义了错误,报错提示了这个单词