异常情况:
异常情况以类的形式出现,每一个异常都是一个类,而这些类之中具有继承关系。
举个例子:object--->BaseException---->Eception---->以树状型分支的各种Error
其中,object是所有类的父类,BaseException作为它的子类之一,管理着所有异常情况,而Exception又是BaseException的子类之一,管理着大部分的异常情况,而具体的异常又是Exception的子类,在它们的类里对具体的异常有着具体的描述。
异常基础:
1.异常是程序运行的时候的报错,XXXError
2.当出现异常时,程序自上而下的寻找合适的 except 类型,进而执行里面的代码
3.可以用级别高的异常(Exception)来做出包括一系列异常的反应动作,它使用时要放在最下面,
当上面的异常类型都排除后,再执行它
异常格式:
情况一:多异常类型,代表异常的多出口
try:
可能出现异常的代码
except 异常类型1:
出现该异常时执行的代码
except 异常类型2:
出现该异常时执行的代码
情况二:获取Exception的错误原因(系统自动给出原因)
try:
可能出现异常的代码
except Exception as err:
print(err) #打印错误原因
情况三:使用了else
try:
可能出现异常的代码
except 异常类型1:
出现该异常时执行的代码
except 异常类型2 :
出现该异常时执行的代码
else:
如果try里没有发生异常执行的代码
注意:如果使用了else,则在try代码范围内不能出现return
情况四:
try:
pass
except:
pass
finally:
无论是否有异常都会被执行的代码(比如文件读写操作时的关闭通道)
异常用法:
##写一个简单计算器的函数(用到异常机制)
def func():
try:
n1 = int(input('输入第一个数字:'))
n2 = int(input('输入第二个数字:'))
result = input('输入一个运算符(+ - * /):')
if result =='+':
num = n1 + n2
print('和是:',num)
elif result=='-':
num = n1-n2
print('差是:',num)
elif result =='*':
num = n1*n2
print('积是:',num)
elif result=='/':
num = n1/n2
print('商是:',num)
else:
print('请输入正确的运算符!')
with open(r'D:\测试(test)文件夹\Test1\result.txt','w') as wstream:
wstream.write('结果是:{}'.format(num))
with open(r'D:\测试(test)文件夹\Test1\result.txt') as rstream:
result = rstream.read()
print(result)
except ValueError:
print('必须输入数字!')
except ZeroDivisionError:
print('除数不能为0!')
except FileNotFoundError:
print('在D:\测试(test)文件夹\Test1下没有找到result文件')
except Exception as err: #Exception应该放在代码的下部分,因为它的权力很大
print('出错了!',err)
func()
finally关键字的机制:
当出现以下情况时,func()的返回值会是多少呢?
def func():
stream = None
try:
stream = open(r'D:\测试(test)文件夹\Test1\books.txt', encoding='utf-8')
print(stream)
container = stream.read()
print(container)
return 1 # 遇到finally时不会立刻返回
except Exception as err:
print(err)
return 2
finally:
print('-----finally-----')
if stream: # 如果stream占用内存
stream.close()
return 3 # 最终还是要返回finally的值
x = func() # 最终返回3,由于finally优先级高于return
print(x)
最后的返回值是:3
当异常结构里出现了finally时,它里面的内容必须要执行,即使执行了try或者except里的return,还是要执行finally,而且finally里面也有return时,会覆盖掉之前的return
自定义异常(raise):
raise关键字:用来抛出异常,处理特殊情况下人为设定的异常情况
使用raise时,有抛出异常就要有接收异常。
##写一个注册函数(自定义异常)
# 注册函数 用户名必须大于6位
def register():
username = input('请输入用户名:')
if len(username) < 6:
raise Exception('用户长度必须6位以上') #自定义异常类型和格式
else:
print('输入的用户名是:', username)
try:
register()
except Exception as err: #可用来接住 上面抛出的 格式相同的异常
print(err) #err是上面的Exception里的自定义异常
print('注册失败!')
else:
print('注册成功!')
注意:下面的except接收的 异常类型 级别要高于或等于 raise 抛出的异常类型
即:except 异常类型> raise 异常类型
err即为上面代码抛出的自定义异常