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  跳出异常
try...except...

 

四.用户自定义异常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
exception

 

五.抛出异常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']
raise

 

六.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'
finally

 

七.标准异常

 

八.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
自定义上下文管理器2
 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 资源释放
上下文管理器3

 

猜你喜欢

转载自www.cnblogs.com/yu-liang/p/8658578.html