Python错误和异常处理
酷尔。 人气:0前言
继续更新Python基础语法,到目前为止Python基础语法已经接近了尾声,本次错误与异常处理更新完后会对文件、数据库、包管理、模块管理、正则表达式的使用进行更新。完成这几个大致的任务之后将会更新爬虫与数据分析。本专栏所写的东西非常的适用初学者,当然也非常适合老手,每一部分都有很全面的编程技巧。相信大家看完后会感觉受益匪浅。(文末附有常见异常表)
异常与错误的概念
错误顾名思义就是由于某种原因,产生了不符合我们预期的结果。我们的代码在运行时非常的有可能出现错误,我们有时又称这种现象为BUG,在Python中异常通常指的是我们的Python解释器发现了我们程序中存在的错误,自己无法解决该错误的时候向操作系统提出了报告引发程序中断。正如现实中我们个人犯错而监管我们的人发现我们的错误,发现我们的异常举动并进行处理。及时帮我们纠正错误行为。
错误分类
语法错误
语法错误又称为编译错误,是计算机操作系统在执行你的代码的时候,由于你代码存在语法性问题无法开始执行程序导致的错误,一般就是函数名、关键字用错导致或者进行导包的时候导入了不存在的包。随着编译器的迭代更新不断变强,这种错误已经非常少见了。Python中编译错误提示SyntaxErrorl例如下图(缺少一半括号):
运行时错误
运行时错误指的是程序通过了编译,计算机操作系统开始执行你的程序在代码执行过程中出由于编程者的疏忽,产生了代码之间的矛盾导致的错误。例如:没有考虑到数组边界或者变量范围导致数组越界、零除异常...这种错误会导致你的程序突然就挂掉一定情况下会造成灰常大的损失。例如以下情况:
逻辑错误
这种错误往往是人们最烦恼的错误,因为操作系统不会直接抛出异常给我们看,你的程序也可以正常运行,但是对程序输入值之后得到的结果就是不对。非常的气人,我们能改进这种错误的方式就是baidu、动脑思考、进行调试、实在不行找个老鸟帮你看看。常见的错误有:死循环、表达式错误、局部全局变量混用....
异常处理机制
捕获异常并处理
Python中采用了结构化的异常处理机制我们可以通过try对异常进行捕获,然后在except中进行异常的处理。最后在finally中进行资源释放之类的工作(有没有异常finally中的代码都会执行),与其他语言不同的是,在Python中引入了一个else机制,else中的语句只有在try中的代码没有异常的时候才会执行。有异常就不执行。详细操作见下面代码,正如所见,可以对多个类型的异常进行捕获。对多个异常进行捕获的话需要将类型涵盖范围较小的异常放在前面,而在捕获之前一般由try代码块中的代码或者函数进行异常的抛出
# 异常的捕获 a=int(input('输入除数:')) b=int(input('输入被除数:')) try: res=a/b except ZeroDivisionError: print('除数不可以为0') # 相同处理方式的异常可以这么写 except (BaseException,TypeError): print('有错误') else: print('您的结果为',res) finally: print('感谢使用!')
主动抛出异常
我们可以轻松的进行异常的捕获并进行解决。但是有时候我们有一种需求就是将错误抛出给上一层进行处理。这时候主动抛出异常就登场了。在Python中主动抛出异常使用的是raise关键字。raise关键字一般与自定义异常类一块进行使用,所以大家先记住raise是主动抛出异常的关键字,待会到自定义异常类处看代码即可。
断言处理
断言处理使用语法为:assert <布尔表达式>或者assert <布尔值表达式> , <字符串表达式>。assert会先对布尔值表达式进行判断,如果表达式为True就不进行操作,否则会抛出异常。并在抛出的异常中输出字符串表达式的信息。具体操作可以看以下代码:
''' 3 录入一个学生的成绩,把该学生的成绩转换为A优秀、B良好、C合格、D不及格的形式, 最后将该学生的成绩打印出来。要求使用assert断言处理分数不合理(小于0或者大于100)的情况 请编写程序。 ''' n=int(input()) assert n in range(101),"您输入的成绩不合理!" if n>=85: print("优秀!") elif n>=70: print("良好!") elif n>=60: print("合格!") else: print("不及格!")
自定义异常类
Python官方库中提供了一系列的异常处理类,在Python中所有的异常均由类实现,所有的异常类又继承自BaseException类,程序运行时出现的异常大多继承自Exception类。Python支持自定义异常类。自定义异常类一般继承Exception或者其子类名称一般以Exception或者Error命名。
自定义异常类以及主动抛弃异常
''' 自己定义一个异常类,继承Exception类, 捕获下面的过程:判断input()输入的字符串长度是否小于5, 如果小于5,比如输入长度为3则输出:"The input is of length 3, expecting at least 5“, 大于5则输出"success”。 ''' class StrLenError(Exception): def __init__(self,s): Exception.__init__(self,s) self.s =s def __str__(self): return f"The input is of length {len(self.s)}, expecting at least 5" n=input() if len(n)<=5: raise StrLenError(n) else: print("success")
常见异常及释义
以下是一些常见的类及引发该类异常的错误描述:
类名 | 描述 |
---|---|
SyntaxError | 发生语法错误时引发 |
FileNotFoundError | 未找到指定文件或目录时引发 |
NameError | 找不到指定名称的变量时引发 |
ZeroDivisionError | 除数为0时的异常 |
IndexError | 当使用超出列表范围的索引时引发 |
KeyError | 当使用映射不存在的键时引发 |
AttributeError | 当尝试访问未知对象属性时引发 |
TypeError | 当试图在使用a类型的场合使用b类型时引发 |
附:用户自定义异常实例
你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承,例如:
>>> class NewError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) >>> try: raise NewError(2*2) except NewError as e: print('New exception occurred, value:', e.value) My exception occurred, value: 4 >>> raise NewError('oops!') Traceback (most recent call last): File "<stdin>", line 1, in ? __main__.NewError: 'oops!'
在这个例子中,类 Exception 默认的 init() 被覆盖。
当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类:
class Error(Exception): """Base class for exceptions in this module.""" pass class InputError(Error): """Exception raised for errors in the input. Attributes: expression -- input expression in which the error occurred message -- explanation of the error """ def __init__(self, expression, message): self.expression = expression self.message = message class TransitionError(Error): """Raised when an operation attempts a state transition that's not allowed. Attributes: previous -- state at beginning of transition next -- attempted new state message -- explanation of why the specific transition is not allowed """ def __init__(self, previous, next, message): self.previous = previous self.next = next self.message = message
大多数的异常的名字都以"Error"结尾,就跟标准的异常命名一样。
总结
加载全部内容