python3 异常
一.错误
1.没法通过其他代码进行处理的问题
2.错误分为语法错误和逻辑错误
二.异常
1.语法和逻辑正确时,运行期检测到的错误被称为异常,可以通过其他代码进行修复
2.大多数的异常都不会被程序处理,都以错误信息的形式展现
3.错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息
4.如果不处理异常,可能导致程序被终止执行,软件崩溃
5.可以添加容错处理进行预防异常
三.捕捉异常try...except...else...finally
1.一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常,但最多只有一个分支会被执行,即从上往下检测try的内容,检测到第一个匹配的异常抛出并结束检测
2.最后一个except子句可以忽略异常的名称,它将被当作通配符使用
3.处理程序将只针对对应的try子句中的异常进行处理,而不是其他的 try 的处理程序中的异常
4.一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,但只能依次匹配捕捉一个异常
5.else子句必须放在所有的except子句之后,将在try子句没有发生任何异常的时候执行
6.except子句后面可以加as来接收异常的形参
7.如果异常名称不确定而又想捕捉,可以直接写Excption
8.BaseException所有内建异常的基类----Exception异常类---所有内置的,非系统退出的异常和用户自定义的异常
9.异常处理并不仅仅处理那些直接发生在try子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常

1 while True:
2 try:
3 x = int(input("Please enter a number: "))#首先执行try子句,try和except之间的语句
4 break
5 # 没有异常发生,忽略except子句,try子句执行后结束
6 #在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略
7 #异常的类型和except之后的名称相符,那么对应的except子句将被执行。最后执行try语句之后的代码
8 # 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中
9 except ValueError:
10 print("Oops! That was no valid number. Try again ")
11 #break 跳出异常
四.用户自定义异常exception
1.创建一个新的exception类来拥有自己的异常,异常应该继承自 Exception 类,或者直接继承,或者间接继承

1 #自定义一个异常并用raise引发
2 class RhhError(Exception):
3 def __init__(self):
4 Exception.__init__(self)
5 try:
6 i=8
7 if i>7:
8 raise RhhError()
9 except RhhError:
10 print('RhhError:错了')
11 --------------------------------------------------------------
12 RhhError:错了
2.当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类

1 import math
2 for i in range(10):
3 try:
4 input_number=input('输入数字')
5 if input_number=='q':
6 break
7 result=1/math.log(float(input_number))
8 print(result)
9 except Exception:
10 print('Error')
11 ------------------------------------------------------------
12 输入数字1
13 Error
14 输入数字3
15 0.9102392266268373
16 输入数字7
17 0.5138983423697507
18 输入数字w
19 Error
20 输入数字q
五.抛出异常raise
raise 唯一的一个参数指定了要被抛出的异常,它必须是一个异常的实例或者是异常的类

1 class TangError(ValueError):
2 pass
3 cur_list=['tag','s','ssff']
4 while True:
5 cur_input=input()
6 if cur_input not in cur_list:
7 raise TangError('Invalid input %s' % cur_list)
8 -------------------------------------------------------------------------
9 s
10 sss
11 Traceback (most recent call last):
12 File "E:/python_work/python.3.14.py", line 35, in <module>
13 raise TangError('Invalid input %s' % cur_list)
14 __main__.TangError: Invalid input ['tag', 's', 'ssff']
六.finally 子句
1.不管 try 子句里面有没有发生异常,finally 子句都会执行
2.如果一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后再次被抛出

1 def divide(x, y):
2 try:
3 result = x / y
4 except ZeroDivisionError:
5 print("division by zero!")
6 else:
7 print("result is", result)
8 finally:
9 print("executing finally clause")
10 print(divide(2,1))
11 print(divide(2,0))
12 ---------------------------------------------------------------
13 result is 2.0
14 executing finally clause
15 None
16 division by zero!
17 executing finally clause
18 None
19 #############################################
20 print(divide('2',1))
21 -------------------------------------------
22 Traceback (most recent call last):
23 executing finally clause
24 File "E:/python_work/python.3.14.py", line 48, in <module>
25 print(divide('2',1))
26 File "E:/python_work/python.3.14.py", line 39, in divide
27 result = x / y
28 TypeError: unsupported operand type(s) for /: 'str' and 'int'
七.标准异常
八.with语句
1.不过出现什么异常,最终都要执行一些清理操作,
2.适用于执行一段代码A之前,进行预处理,执行代码A结束后,进行清理操作
3.with open(file1) as f1,open(file) as f2:
4.上下文管理器:固定上下,中间代码可以改变

1 #自定义上下文管理器
2 class test:
3 def __enter__(self):
4 print('enter')
5 return self
6 def __exit__(self, exc_type, exc_val, exc_tb):#(自身,异常类型,异常值,异常追踪信息)
7 print(self, exc_type, exc_val, exc_tb)
8 import traceback
9 traceback.extract_tb(exc_tb)#提取追踪信息
10 print('exit ')
11 return True#返回true则表示不会再对外界抛出异常,默认返回False抛出异常
12
13 with test() as x:#x为enter方法返回值
14 print('boby',x)
15 print(1/0)
16 -------------------------------------------------------------
17 enter
18 boby <__main__.test object at 0x035AC4B0>
19 <__main__.test object at 0x035AC4B0> <class 'ZeroDivisionError'> division by zero <traceback object at 0x058E9080>
20 exit

1 import contextlib
2 #借助装饰器把生成器变成上下文管理器
3 @contextlib.contextmanager
4 def test():
5 print(1)
6 yield 'xxx'#yield前面的语句当做enter,yield后面的语句当做exit
7 print(2)
8 with test() as x:#x的值为yield后面的值
9 print(3,x)
10
11
12 @contextlib.contextmanager
13 def ze():
14 try:
15 yield
16 except ZeroDivisionError as e:
17 print('error',e)
18 with ze() as z:
19 print(1/0)
20 -------------------------------------------------------------
21 1
22 3 xxx
23 2
24 error division by zero

1 class test:
2 def t(self):
3 print('ttt')
4 def close(self):
5 print('资源释放')
6 # def __enter__(self):
7 # return self
8 # def __exit__(self, exc_type, exc_val, exc_tb):
9 # self.close()
10
11 import contextlib#让拥有close方法的对象快速变成一个上下文管理器
12 with contextlib.closing(test()) as t_obj:
13 t_obj.t()
14 ---------------------------------------
15 ttt
16 资源释放