Python之异常处理

一、基本概念

'''
1、什么是异常
    异常是错误发生的信号,
    程序一旦出错,如果程序中还没有相应的处理机制
    那么该错误就会产生一个异常抛出来
    程序的运行也随之终止

2、一个异常分为三部分:
    1、异常的追踪信息
    2、异常的类型
    3、异常的值

3、异常的分类:
    1、语法异常:
        这类异常应该在程序执行前就改正
        print('start....')
        x=1
        x+=1
        if
        print('stop....')

    2、逻辑上的异常

'''

二、常见异常类型

IndexError-# l=['a','b']--------索引错误
l[100]

''''''
KeyError
d={'a':1}
d['b']

''''''
AttributeError:---------属性错误
class Foo:
    pass

Foo.x
import os
os.aaa

''''''
ZeroDivisionError-------零不能做被除数错误
1 / 0

''''''
FileNotFoundError-------文件不存在错误
f=open('a.txt','r',encoding='utf-8')

''''''
ValueError: I/O operation on closed file.----------值错误
f=open('a.txt','r',encoding='utf-8')
f.close()
f.readline()

ValueError: invalid literal for int() with base 10: 'aaaaa'
int('aaaaa')

''''''
TypeError---------类型错误,被循环数不可迭代
for i in 333:
    pass

''''''
NameError-------名字错误:变量名没有定义
x
func()


def func():
    import os
    os.xxxx

func()

三、try.....except捕获异常

# 语法:

# 单分支
try:
    print('start.....')
    x=1
    y           #-------检测到异常,会直接执行except,而不会在执行程序内的代码块
    l=[]
    l[3]
    d={'a':1}
    d['b']
    print('end....')     #-----不会被执行。只有被被检测的代码块没有异常才能被执行到
except NameError:
    print('变量名没有定义')
print('other.....')



# 多分支
try:          #-------一个try后面可以跟多个捕获的异常类型,但只会被执行一个
    print('start.....')
    x=1
    # y
    l=[]
    l[3]
    d={'a':1}
    d['b']
    print('end....')
except NameError:               #一种异常类型只能捕获自己的异常类型,而不能捕获该异常类型之外的异常类型
    print('变量名没有定义')
except KeyError:
    print('字典的key不存在')
except IndexError:
    print('索引超出列表的范围')
#如果被检测的代码抛出的异常类型,以上的异常类型都没有,一样会报错,这是我们可以使用万能异常类进行解决
print('other.....')




# 多种异常采用同一段逻辑处理
try:
    print('start.....')
    x=1
    # y
    l=[]
    # l[3]
    d={'a':1}
    d['b']
    print('end....')
except (NameError,KeyError,IndexError):         #检测代码块中的异常是否是该异常类型中的一种,是的话下面的代码将会正常的执行,不是则会报错
    print('变量名或者字典的key或者列表的索引有问题')


print('other.....')

四、万能异常

# 万能异常
try:
    print('start.....')
    x=1
    # y
    l=[]
    # l[3]
    d={'a':1}
    # d['b']
    import os
    os.aaa
    print('end....')
except Exception:        #无论被检测的代码块是什么异常,都会被万能异常捕获到
    print('万能异常---》')

print('other.....')



# 获取异常的值,通过as赋值给变量e,通过打印就能看到返回结果
try:
    print('start.....')
    x=1
    y
    l=[]
    l[3]
    d={'a':1}
    d['b']
    import os
    os.aaa
    print('end....')
except Exception as e:       #通过as可以拿到抛出异常类型的值,这样打印就可以看到抛出异常类型的值
    print('万能异常---》',e)

print('other.....')




try:
    print('start.....')
    x=1
    # y
    l=[]
    l[3]
    d={'a':1}
    d['b']
    import os
    os.aaa
    print('end....')
except NameError as e:          #不同异常类型都可以使用as,均可通过打印看到异常类型的值
    print('NameError: ',e)

except KeyError as e:
    print('KeyError: ',e)

except Exception as e:
    print('万能异常---》',e)

print('other.....')

五、try....else..以及try....finally.....

# try....else...
"""else: 不能单独使用,必须与except连用,意思是:else的子代码块会在被检测的代码没有出现过任何异常的情况下执行"""
try:
    print('start.....')
    # x=1
    y
    # l=[]
    # l[3]
    # d={'a':1}
    # d['b']
    # import os
    # os.aaa
    print('end....')
except NameError as e:
    print('NameError: ',e)

except KeyError as e:
    print('KeyError: ',e)

except Exception as e:
    print('万能异常---》',e)
'''只有以上异常类型都没有被执行,才会执行else内的函数体代码,也就是说被检测到的代码没有异常才会执行else内的代码'''
else:        #万能模板执行就不会执行else的内容,except类似于elif语句,一个成立,就不会执行其他的条件
    print('在被检测的代码块没有出现任何异常的情况下执行')         #
print('other.....')


"""try...finally....#无论有没有发生异常都会被执行"""
try:
    print('start.....')
    # x=1
    # # y
    # l=[]
    # l[3]
    # d={'a':1}
    # d['b']
    # import os
    # os.aaa
    print('end....')
except NameError as e:
    print('NameError: ',e)

except KeyError as e:
    print('KeyError: ',e)

except Exception as e:
    print('万能异常---》',e)

else:
    print('在被检测的代码块没有出现任何异常的情况下执行')
finally:          #---------无论异常发生与否finally内函数体代码都会被执行
    print('无论有没有异常发生,都会执行')
print('other.....')




"""finally的子代码块中通常放回收系统资源的代码"""
try:
    f=open('a.txt',mode='w',encoding='utf-8')
    f.readline()

finally:
    f.close()        #有没有异常都会被执行,放回收资源的代码块,即使有异常文件也会被关闭

print('other....')

六、主动触发异常及自定义异常类型

"""主动触发异常,条件不成立使用raise TypeError主动触发异常"""
raise TypeError('类型错误')        #这样我们可以看到主动抛出异常类型以及异常类型的值,异常类型其本质就是一个类,类加括号就是调用一个类产生一个对象



class People:
    def __init__(self,name):
        if not isinstance(name,str):
            raise TypeError('%s 必须是str类型' %name)

        self.name=name

p=People('egon')





# 断言        #------很少会用,了解
print('part1........')
stus=['egon','alex','wxx','lxx']
stus=[]

if len(stus) <= 0:
    raise TypeError           #TypeError后面内容可以没有,主动抛出异常后,程序后面的代码就不会别执行了
assert len(stus) >0            #条件满足则断言生效,生效一次(即bool值为True时),条件不满足时,则会抛出异常:AssertionError

print('part2.........')
print('part2.........')
print('part2.........')
print('part2.........')
print('part2.........')
print('part2.........')


#重点
"""自定义异常"""
class RegisterError(BaseException):       #BaseException是所以异常类型的父类。
    def __init__(self,msg,user):
        self.msg=msg
        self.user=user

    def __str__(self):                    #会在打印的时候自动触发
        return '<%s:%s>' %(self.user,self.msg)        #返回的必须是字符串

raise RegisterError('注册失败','teacher')
原文地址:https://www.cnblogs.com/sui776265233/p/9263572.html