LOADING

正在加载

Python的检察官(八)——异常处理

一、异常处理的用处何在?

有的时候由于代码执行错误我们可以看见一些错误信息,那就是异常,异常并不是错误,而是因为特殊原因,例如 用户使用错误、网络,通常情况下,异常一旦出现,程序会立刻结束掉,这时我们可以通过这些信息了解到语句在哪里出现错误并可以及时处理,这就是异常处理。

哪有有人问了,系统不是都已经告诉我们错误信息了吗?为啥还有学习?学习怎么看?

看只是其中的一种,我们还可以学会自己捕抓,并及时做出处理,好像还是说不到点子上。举个例子吧!比如说电脑蓝屏(估计很多人都经历过),当蓝屏时,我们就不可以对的电脑执行除关机冲重启以外的操作了,那想想这时我们在写一些很重要的文件或者代码时,突然蓝屏了,那数据不是就丢失了吗?那有没有其他的方法改进呢?比如先保存后在蓝屏,答案是有的,就是我们可以预测可能发生异常的代码块,并进行捕抓,然后进行自己想要的处理。

异常处理的作用:

(1).解决错误 except里面处理
(2).保证代码的健壮性和稳定性、容错性

二、异常处理语句

那么知道这是个啥东西了,那么我们就得学会使用它。在Python中,异常处理语句是以try...except语句为中心扩展开来的。try语句必须有配套语句。

1.try…excetp语句

在Python中我们使用try语句进行异常捕抓,并用except语句进行异常处理。当try语句内没有异常时将跳过except语句,进行其以为的语句。

格式

try:
…可能出现异常的语句块
except:
…对异常进行处理

代码

try:
    num = float(input("请输入数字:"))
    print("如果没有异常将执行此语句")
except:
    num = 0
    print("如果有异常将执行此语句")
print("不管有没有异常都执行此语句")

结果显示

在这里插入图片描述
有结果我们可以看出输入一个汉字时,脚本是应该报错的,结果没有报错,而是执行except
语句里面的代码块。

2.对特定的异常进行异常处理

在很多时候语句的错误是多样化的,可能是文件错误,也可以是类型错误,中断错误等等。这时我们就可以做出相应的异常处理。当执行到对应异常后,直接跳出except语句外执行其他语句,except的特殊语句异常是可以多个匹配的。

那前面不是可以一下子把异常捕抓进行处理吗?现在一一处理会不会比较麻烦?

是肯定会的,在编写代码的时候是复杂的,但是却可以为后期的维护省了许多事,比如,知道是文件错误,我们就可以单独对文件进行处理,而不是所有代码都进行处理。

格式

try:
…可能出现异常的语句块
except 特殊异常1[as 变量名]:
…对特殊异常1进行对应处理
except (特殊异常2, 特殊异常3):
…对特殊异常2,3进行对应处理

(特殊异常2, 特殊异常3)这个代码的意思是将对不同特殊异常进行同样处理。
这里的[as 变量名]的意思是将异常信息传递给一个变量,是用来显示出现的错误信息的,很多情况下我们会将这种错误信息存储在日志中方便以后的维护。

代码

try:
    num = float(input("请输入数字:"))
    print("如果没有异常将执行此语句")
except AssertionError:
    print("assertion异常")
except ValueError as next_1:
    print(next_1)
    print("value异常")
except FileNotFoundError:
    print("文件异常")
except BaseException:	#建议在是所有异常最后添加except BaseException异常处理,对剩余异常一次做处理
    print("最后剩下的未知异常将执行此语句")
print("不管有没有异常都执行此语句")

结果显示
在这里插入图片描述
异常类的继承关系:普通异常类继承了Exception类,Exception类又继承了BaseException类,BaseException异常处理是对所有异常进行处理。而语法except:except BaseException是差不多的。

3.心细的finally语句

finally语句是一个非常心细的语句,就是在脚本由于错误没有执行完时,未完成但必须执行的代码进行强制执行的语句,比如说内存释放等问题,当文件打开时,由于打开错误,没有及时收回内存,这时我们就可以使用try语句,强制收回内存。就是说无论try语句有没有捕抓到错误,都将必须强制执行的语句。

注意:如果使用os._exit()函数的话,就不会执行finally语句内的语句块

格式

try:
…可能出现异常的语句块
except 特殊异常1:
…对特殊异常1进行对应处理
except 特殊异常2:
…对特殊异常2进行对应处理
finally:
…强制执行语句块

代码

try:
    num = float(input("请输入数字:"))
    print("如果没有异常将执行此语句")
except AssertionError:
    print("assertion异常")
except ValueError:
    print("value异常")
except FileNotFoundError:
    print("文件异常")
except BaseException:	#建议在是所有异常最后添加except BaseException异常处理,对剩余异常一次做处理
    print("最后剩下的未知异常将执行此语句")
finally:
    print("强制执行此语句")

结果显示
在这里插入图片描述

三、自定义异常

不仅仅有系统提供的异常,也可以由我们来自己定义异常,为什么要自己定义呢?假如我们做一个手机号码记录器希望用户输入的是号码号码,而一般情况下号码都是十一位数字,这时系统是没有对十一位数字进行抛出异常的,所以就需要我们进行号码的异常处理了。人为的抛出异常的目的就是向调用者传递信息。

步骤如下

定义一个类
让这个类继承Exception或者BaseException
重构初始化方法
并用关键字raise捕抓异常

格式

class 自定义异常名字(Exception或者BaseException都行):
…def init(self):
… …对捕抓的异常进行异常处理
raise 捕抓异常(想要加的提示信息,可以不加,默认)

代码

class LongExceptin(BaseException):
    def __init__(self,leng):
        self.leng = leng
    def __str__(self):
        print("\n号码不对")
num = input("电话号码:")
if len(num) != 11:
    raise LongExceptin(len(num))
else:
    print(num)

显示结果
7ea8bdba4c3bd9671ea017eac767de59.png

四、捕获异常及方法总结

异常名称 描述
BaseException 所有异常的基类
SystemExit 解释器请求退出
KeyboardInterrupt 用户中断执行(通常是输入^C)
Exception 常规错误的基类
StopIteration 迭代器没有更多的值
GeneratorExit 生成器(generator)发生异常来通知退出
SystemExit Python解释器请求退出
StandardError 所有的内建标准异常的基类
ArithmeticError 所有数值计算错误的基类
FloatingPointError 浮点计算错误
OverflowError 数值运算超出最大限制
ZeroDivisionError 除(或取模)零(所有数据类型)
AssertionError 断言语句失败
AttributeError 对象没有这个属性
EOFError 没有内建输入,到达EOF标记
EnvironmentError 操作系统错误的基类
IOError 输入/输出操作失败
OSError 操作系统错误
WindowsError 系统调用失败
ImportError 导入模块/对象失败
KeyboardInterrupt 用户中断执行(通常是输入^C)
LookupError 无效数据查询的基类
IndexError 序列中没有没有此索引(index)
KeyError 映射中没有这个键
MemoryError 内存溢出错误(对于Python解释器不是致命的)
NameError 未声明/初始化对象(没有属性)
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weakreference)试图访问已经垃圾回收了的对象
RuntimeError 一般的运行时错误
NotImplementedError 尚未实现的方法
SyntaxError Python 语法错误
IndentationError 缩进错误
TabError Tab 和空格混用
SystemError 一般的解释器系统错误
TypeError 对类型无效的操作
ValueError 传入无效的参数
UnicodeError Unicode相关的错误
UnicodeDecodeError Unicode解码时的错误
UnicodeEncodeError Unicode编码时错误
UnicodeTranslateError Unicode转换时错误
Warning 警告的基类
DeprecationWarning 关于被弃用的特征的警告
FutureWarning 关于构造将来语义会有改变的警告
OverflowWarning 旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning 关于特性将会被废弃的警告
RuntimeWarning 可疑的运行时行为(runtimebehavior)的警告
SyntaxWarning 可疑的语法的警告
UserWarning 用户代码生成的警告
这是一个较全的Python捕获异常的博文:链接在此

建议:在写异常处理是通常我们都想知道错误信息,那么我们可以使用as,将错误信息赋值到一个变量上

try:
    num = float(input("请输入数字:"))
    print("如果没有异常将执行此语句")
except AssertionError as i:
    print("assertion异常")
    print("错误信息为:{}".format(i))
except ValueError as i:
    print("value异常")
    print("错误信息为:{}".format(i))
except FileNotFoundError as i:
    print("文件异常")
    print("错误信息为:{}".format(i))
except BaseException as i:	#建议在是所有异常最后添加except BaseException异常处理,对剩余异常一次做处理
    print("最后剩下的未知异常将执行此语句")
    print("错误信息为:{}".format(i))
finally:
    print("强制执行此语句")

补充:还有else只在没有异常的时候执行

try:
    divide(1,1)
except:
    print("divide by 0")
else:
    print("the code is no problem")
 
print("code after try catch,hello,world!")

9344968d40dfb2e6cd20f631635630ab.png

avatar
小C&天天

修学储能 先博后渊


今日诗句