2023年11月27日发(作者:)

异常处理

Python 有两种错误很容易辨认:语法错误和异常(本⽂将重点介绍python的异常)

python语法错误:

Python 的语法错误或者称之为解析错,是初学者经常碰到的;

>>>while True print('Hello world')

File "", line 1, in ?

while True print('Hello world')

^

SyntaxError: invalid syntax

函数 print() 被检查到有错误,是它前⾯缺少了⼀个冒号 : 。语法分析器指出了出错的⼀⾏,并且在最先找到的错误的位置标记了⼀个⼩⼩的箭头。

python异常:

即便 Python 程序的语法是正确的,在运⾏它的时候,也有可能发⽣错误。运⾏期检测到的错误被称为异常。异常即是⼀个事件,该事件会在程序执⾏过程中

发⽣,影响了程序的正常执⾏;⼀般情况下,在Python⽆法正常处理程序时就会发⽣⼀个异常;异常是Python对象,表⽰⼀个错误;当Python脚本发⽣异常

时我们需要捕获处理它,否则程序会终⽌执⾏。

>>>10 * (1/0) # 0 不能作为除数,触发异常

Traceback (most recent call last):

File "", line 1, in ?

ZeroDivisionError: division by zero

>>> 4 + spam*3 # spam 未定义,触发异常

Traceback (most recent call last):

File "", line 1, in ?

NameError: name 'spam' is not defined

>>> '2' + 2 # int 不能与 str 相加,触发异常

Traceback (most recent call last):

File "", line 1, in ?

TypeError: Can't convert 'int' object to str implicitly

异常以不同的类型出现,这些类型都作为信息的⼀部分打印出来: 例⼦中的类型有 ZeroDivisionErrorNameError TypeError。错误信息的前⾯部分显⽰了

异常发⽣的上下⽂,并以调⽤栈的形式显⽰具体信息。

python异常的处理:

python提供了两个⾮常重要的功能来处理python程序在运⾏中出现的异常和错误。你可以使⽤该功能来调试python程序。异常处理断⾔(Assertions)

异常处理涉及的5个关键字:

try:理解它是扫描器,将可能出现异常的代码放⼊其中;如果在执⾏的过程中出现异常对象了,扫描器会⽴即察觉到此异常对象,但是它没有处理它的能⼒,

所以会将异常对象给到except(捕获器)进⾏处理。

except:理解它是捕获器,后⾯可以定义异常类型,并且和as关键字配合使⽤;定义多个except是合法的,但是它的执⾏顺序是有由上往下,⼀旦匹配上某个

except,之后的就不执⾏了;匹配成功就理解将异常对象捕获住并且kill,顺便会执⾏except内部的代码。(注意:)

except不能捕获处理类似于语法错误这种情况

finally:将⼀定需要被执⾏的代码定义其中,【记住】:finally⼀定会被执⾏(核⼼);使⽤场景:像关闭⽂件、断开数据库连接等⾏为都可以放⼊到finally中。

else:位置在finally前,except后;效果/作⽤类似于循环;没有异常对象出现,else就会被执⾏,反之不会被执⾏。

raise:⼿动抛出⼀个异常类型的对象,定义:raise 异常类型(msg)

定义格式:

格式⼀: 多个except语句并列存在,每个except包含⼀种类型,如果它们之间没有⼦⽗类的关系(互斥),那么谁上谁下⽆所谓, 如果它们之间存在⼦⽗类的

关系(包含),那么⼩的在上,⼤的在下。

try:

语句块1

except 异常类型1 as e:

语句块2

except 异常类型2 as e:

语句块3

except 异常类型3 as e:

语句块4

finally:

语句块5

格式⼆:⼀个except具备多个捕获能⼒(捕获多种不同类型异常对象)

try:

语句块1

except 异常类型1 as e:

语句块2

except 异常类型2 as e:

语句块3

except 异常类型3 as e:

语句块4

except (异常类型4,异常类型5,...,异常类型m) as e:

finally:

语句块5

格式三:Exception是所有异常类型的⽗类型,它都是定义在最后⼀个except的位置。

try:

语句块1

except 异常类型1 as e:

语句块2

except 异常类型2 as e:

语句块3

except 异常类型3 as e:

语句块4

except (异常类型4,异常类型5,...,异常类型m) as e:

语句块5

except Exception as e:

语句块6

finally:

语句块7

格式四: Exception的简化版使⽤】:如果定义了except,那么它必须是最后⼀个except,它可以理解为是Exception的简化形式

try:

语句块1

except 异常类型1 as e:

语句块2

except 异常类型2 as e:

语句块3

except 异常类型3 as e:

语句块4

except (异常类型4,异常类型5,...,异常类型m) as e:

语句块5

except:

语句块6

finally:

语句块7

代码演⽰⾃动抛出异常对象:

2

3 def div(a,b):

4 print(a / b)

5

6 div(10,0)

7

8 # 演⽰异常处理的⽅式⼀:try ... except ...

9 try:

10 print(10/0)

11 except ZeroDivisionError as e:

12 print(e)

13

14 try:

15 print("abc"+123)

42

43 except:

44 print('我是Exception的简化形式,我只能出现在最后⼀个except的位置...')

代码演⽰finally语句的使⽤:将⼀定要被执⾏的代码定义在finally中,不管之前的代码怎么样(异常是否被解决)finally⼀定会被执⾏,在后期的学习和开发

中,我们将关闭⽂件、关闭数据库连接等操作都定finally中。

1 try:

2 fr = open(r'C:','r') # ⽂件能打开

3 print(())

4 print(10 / 0)

5 # () # 因为关闭⽂件操作是⼀定要被执⾏的 但是在try⾥⾯也有可能存在风险性,当print(10 / 0)⾏不了,则⽆法执⾏close操作,所以关闭⽂件需要放在finally语句当中

6 except:

7 print('解决异常')

8 finally:

9 print('我是finally,我⼀定会被执⾏...')

10 ()

11

12

13 # 但是如果⼀开始就是⼀个打不开的⽂件,则也没有办法关闭⽂件

14 fr = 0

15 try:

16 fr = open(r'C:','r') # 没有此⽂件名 (⽂件存在则fr不为None值)

17 print(())

18 except:

19 print('解决异常')

20 finally:

21 print('我是finally,我⼀定会被执⾏...')

22 if fr: # frNone值则ifFalse,否则为True,执⾏以下指令(为了安全性)

23 ()

finally案例演⽰⼆(进⼀步理解)

1 # Finally案例:分别输出了哪些内容,返回值是多少

2

3 def func():

4 try:

5 print('我是')

6 print(10 / 2)

7 return 1 #执⾏此步 则函数就结束了,⼜因为finally⼀定要被执⾏,所以return 1不会被执⾏,直接调到finally

8 except:

9 print('我是')

10 return 2

11 finally:

12 print('我是')

13 return 3

14

15 num = func()

16 print(num)

17 '''结果得到是

18 我是

19 5.0

20 我是

21 3'''

22

23 # 如果题⽬改为如下,则

24 def func():

25 try:

26 print('我是')

27 print(10 / 0)

28 return 1

29 except:

30 print('我是')

31 return 2 #执⾏此步 则函数就结束了,⼜因为finally⼀定要被执⾏,所以return 2不会被执⾏,直接调到finally

32 finally:

33 print('我是')

34 return 3

35

36 num = func()

37 print(num)

38 '''结果得到是

39 我是

40 我是

41 我是

42 3'''

43

【补充】操作:不需要程序员⼈为的去书写 close() 函数

1 With open(r'C:','r')as fr:

2 print(())

解决异常也是⼀样:

1 try:

2 with open(r'C:','r') as fr:

3 print(())

4 except:

5 print('解决异常...')

代码演⽰else语句和异常处理机制配合使⽤:如果try中没有出现异常对象,那么else语句就⼀定会被执⾏,如果try中出现了异常对象,就算被处理了,else

是不会被执⾏。

1 try:

2 print('我是')

3 print(10 / 0)

4 except Exception as e:

5 print('我是')

6 else:

7 print('我是')

8 finally:

9 print('我是')

10 #得到

11 我是

12 我是

13 我是

14

15 #如果把print(10 / 0) 改为print(10 / 2)

16

17 #得到

18 我是

19 5.0

20 我是

21 我是

代码演⽰raise的使⽤:(⼿动抛出异常对象)

1 age = 18

2 if age < 0 or age > 130:

3 try:

4 raise Exception('年龄有问题...')

5 except:

6 print('年龄不合法...正在处理')

7 pass

8 else:

9 print('年龄为:%d' %age)

10 print('能⾛吗?')

11

12 #得到结果为

13 年龄为:18

14 能⾛吗?

15

16 #如果第⼀⾏是age=-18

17 #得到结果为

18 年龄不合法...正在处理

19 能⾛吗?

1 # 演⽰异常处理的⽅式⼆:不断往上级传递异常对象,回避问题的⽅式

2

3 def m1():

4 print('我是m1...')

5 print(10 / 0)

6

7 def m2():

8 print('我是m2...')

9 # try:

10 m1()

11 # except:

12 # pass

13

14 def m3():

15 print('我是m3...')

16 try:

17 m2()

18 except:

19 pass

20

21 m3()

22 #得到结果

23 我是m3...

24 我是m2...

25 我是m1...

python标准异常总结:

BaseException所有异常的基类

SystemExit解释器请求退出

KeyboardInterrupt⽤户中断执⾏(通常是输⼊^C)

Exception常规错误的基类

StopIteration迭代器没有更多的值

GeneratorExit⽣成器(generator)发⽣异常来通知退出

StandardError所有的内建标准异常的基类

ArithmeticError所有数值计算错误的基类

FloatingPointError浮点计算错误

OverflowError数值运算超出最⼤限制

ZeroDivisionError(或取模) (所有数据类型)

AssertionError断⾔语句失败

AttributeError对象没有这个属性

EOFError没有内建输⼊,到达EOF 标记

EnvironmentError操作系统错误的基类

IOError输⼊/输出操作失败

OSError操作系统错误

WindowsError系统调⽤失败

ImportError导⼊模块/对象失败

LookupError⽆效数据查询的基类

IndexError序列中没有此索引(index)

KeyError映射中没有这个键

MemoryError内存溢出错误(对于Python 解释器不是致命的)

NameError未声明/初始化对象 (没有属性)

UnboundLocalError访问未初始化的本地变量

ReferenceError弱引⽤(Weak reference)试图访问已经垃圾回收了的对象

RuntimeError⼀般的运⾏时错误

NotImplementedError尚未实现的⽅法

SyntaxErrorPython 语法错误

IndentationError缩进错误

TabErrorTab 和空格混⽤

SystemError⼀般的解释器系统错误

TypeError对类型⽆效的操作

ValueError传⼊⽆效的参数

UnicodeErrorUnicode 相关的错误

UnicodeDecodeErrorUnicode 解码时的错误

UnicodeEncodeErrorUnicode 编码时错误

UnicodeTranslateErrorUnicode 转换时错误

Warning警告的基类

DeprecationWarning关于被弃⽤的特征的警告

FutureWarning关于构造将来语义会有改变的警告

OverflowWarning旧的关于⾃动提升为长整型(long)的警告

PendingDeprecationWarning关于特性将会被废弃的警告

RuntimeWarning可疑的运⾏时⾏为(runtime behavior)的警告

SyntaxWarning可疑的语法的警告

UserWarning⽤户代码⽣成的警告

【注意事项】:

1).finally这种格式是合法的,但是它丧失了解决异常对象的能⼒(所以不会使⽤)

2).else语句必须配合except使⽤,出现位置⼀定是在最后⼀个except的后⾯

3).常见的运⾏时异常类型:ZeroDivisionError:分母为0的异常;TypeError:类型有误的异常; NameError:没有定义就使⽤的异常;IndexError:下标越界

的异;FileNotFoundError:⽂件找不到的异常;...

4).with open ... as ...语句可以优化原始的open操作!体现:它不需要⼿动close()⽂件对象

总结:学习异常对象简单归纳为5个关键字:try except finally else raise

pythonassert(断⾔):

Pythonassert(断⾔)⽤于判断⼀个表达式,在表达式条件为 false 的时候触发异常。断⾔可以在条件不满⾜程序运⾏的情况下直接返回错误,⽽不必等待

程序运⾏后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运⾏,可以先判断当前系统是否符合条件。

语法格式如下:assert expression

等价于:

if not expression:

raise AssertionError

assert 后⾯也可以紧跟参数: assert expression [, arguments]

等价于:

if not expression:

raise AssertionError(arguments)

代码演⽰assert⽰例:

1 >>> assert True # 条件为 true 正常执⾏

2 >>> assert False # 条件为 false 触发异常

3 Traceback (most recent call last):

4 File "", line 1, in

5 AssertionError

6

7 >>> assert 1==1 # 条件为 true 正常执⾏

8 >>> assert 1==2 # 条件为 false 触发异常

9 Traceback (most recent call last):

10 File "", line 1, in

11 AssertionError

12

13 >>> assert 1==2, '1 不等于 2'

14 Traceback (most recent call last):

15 File "", line 1, in

16 AssertionError: 1 不等于 2

17

18

19 # 判断当前系统是否为 Linux,如果不满⾜条件则直接触发异常,不必执⾏接下来的代码:

20 import sys

21 assert ('linux' in rm), "该代码只能在 Linux 下执⾏"

22 # 接下来要执⾏的代码