Python使用被称为对象的特殊对象来管理程序执行期间发生的错误。每当发生让pthon不知所措的错误时,他都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继续运行,否则程序将停止并显示一个traceback,其中包含有关异常的报告。
异常是使用try-except代码块来处理的。代码块让python执行指定的操作,同时告诉python发生异常时怎么办。
处理ZeroDivisionError异常
将一个数字除以零
print(1/0)#报以下错误Traceback (most recent call last): File "D:/pythontest/pycharmt/day9/pitest.py", line 41, inprint(1/0)ZeroDivisionError: division by zero
这种情况下python停止运行并告诉你引发了哪种异常,ZerDivisionError错误是一个异常对象。我们可以增加代码防止这种情况
try: print(1/0)except ZeroDivisionError: print('no zero')
使用try-except代码块来处理可能触发的异常。将可能出错的代码放到try内,在except中放入出错后希望运行的代码。如果没有出错,就跳过except代码中的内容
else 代码块
通过将可能会引发错误的代码放到代码块tr-except中,可提高这个程序抵御错误的能力。有赖于try代码成功执行的代码都应该放到else里
while 1: num_1 = input('enter first num ') num_2 = input('enter second num') try: print(int(num_1)/int(num_2)) except ZeroDivisionError: print('no zero ') else: answer = int(num_1)/int(num_2)
将可能引发错误的代码放入try中,将对触发错误代码后执行的放到except中,将try代码执行成功后要执行的放在else代码块中
通过预测可能发生错误的代码,可编写健壮的程序,他们即便面临无效数据或缺少资源,也能继续运行,从而能抵御无意的用户错误和恶意的攻击
处理FileNotFoundError异常
来读取一个不存在的文件
with open('cc.txt') as file_object: file_txt = file_object.read()Traceback (most recent call last): File "D:/python/pycharmtest/day12/filetest.py", line 15, inwith open('cc.txt') as file_object:FileNotFoundError: [Errno 2] No such file or directory: 'cc.txt
python找不到要打开的文件,于是创建了FileNotFoundError对相关,这个错误时open产生的
ry: with open('cc.txt') as file_object: file_txt = file_object.read()except FileNotFoundError: print('file not found')
分析文本
with open('blog.txt')as file_object:# cont = ''# try:# contents = file_object.read()# for x in contents:# x = ''.join(x.split(' '))# cont += x.strip()# except UnicodeDecodeError:# print('编码错误')# print(cont)# print(len(cont))
使用多个文件
def file_count(file_name): try: with open(file_name) as file_object: contents = file_object.read() except FileNotFoundError: print('%s is not found'%file_name) else: content = ''.join(contents.split()) print('%s count %s'%(file_name,len(content)))file_name = ['blog.txt','pi.txt','cc.txt']for x in file_name: file_count(x)
输出
blog.txt count 20pi.txt count 1197cc.txt is not found
失败时一声不吭
try: with open('no.txt') as file_object: contents = file_object.read()except FileNotFoundError: passelse: print(len(contents.split()))
在找不到文件时pass什么都不做,pass也充当一个占位符的作用
ValueError
while 1: num_1 = input('enter frist num') num_2 = input('enter second num') try: answer = int(num_1)/int(num_2) except ValueError: print('no chr') else: answer = int(num_1)/int(num_2) print(answer)
记录错误
如果不捕获错误,自然还可以让python解释器来打印处错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时让程序继续执行下去
python内置的logging 模块可以非常容易地记录错误信息:
import loggingdef bar1(n): return 10/ndef bar2(n): return bar1(n)*2def main(): try: bar2(0) except Exception as e: logging.exception(e)main()print('end')
同样出错,但程序打印完错误信息后会继续执行,并正常退出
ERROR:root:division by zeroendTraceback (most recent call last): File "D:/pythontest/pycharmt/senior/errortest.py", line 9, in main bar2(0) File "D:/pythontest/pycharmt/senior/errortest.py", line 6, in bar2 return bar1(n)*2 File "D:/pythontest/pycharmt/senior/errortest.py", line 4, in bar1 return 10/nZeroDivisionError: division by zero
抛出错误
因为错误是class,捕获一个错误就是捕获到该class的一个实例。因此,错误并不是凭空产生的,而是有意创建并抛出的。python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以
如果要抛出错误,首先要根据需要,定义一个错误的lclass,选择好继承关系,然后用raise语句抛出一个错误的实例
class FooError(ValueError): '''错误的类,选择继承关系''' passdef foo(s): if s ==0: raise FooError('invalid value : %s' % s)#抛出 return 10/sfoo(0)
执行后,我们最后跟踪对自己定义的错误
Traceback (most recent call last): File "D:/pythontest/pycharmt/senior/errortest.py", line 20, infoo(0) File "D:/pythontest/pycharmt/senior/errortest.py", line 18, in foo raise FooError('invalid value : %s' % s)__main__.FooError: invalid value : 0
只有必要的时候才定义我们自己的错误类型,如果可以你选择python已有的内置的错误类型(比如ValueError,TypeError),尽量使用python内置的错误类型
决不能把一个IOError转换成毫不相干的ValueError
在文档中写清楚可能会抛出那些错误,依旧错误产生的原因
调试
再议logging
把print()替换为logging是检查错误的第三章方式,和assert比,logging不会抛出错误,而且可以输出到文件