一、异常
python中的异常都是通过类实现的,所有的异常类都是继承自基类BaseException,可分为四类如下:
若程序中的异常没有被处理,则默认情况下该异常会被传递给上一级,这就是异常的传递,若上一级仍未处理,则会继续向上传递直至异常被处理或程序崩溃。
二、捕获异常
(一)try…except语句
该语句用于捕获程序运行时时的异常,其中try子句后面跟代码,except子句后跟捕获的异常类型以及当捕获到异常后的处理代码。简单的来说,当try子句中若有异常,则忽略该子句中的剩余代码,立即执行except子句中的代码,而当try子句没有异常则不执行
except子句后的内容。 try: 代码 except(异常类型): 异常处理代码
python中标准异常有以下:python标准异常
例如下列python代码,这里try子句中由于未声明d变量,使产生NameError:未声明/初始化对象 (没有属性)的异常,except子句中检测到异常从而执行正确的代码:
try: a = 1 b = 2 c = a * d print(c) except NameError: c = a * b print(c)
运行结果如下:
1、单个异常
可以通过在异常类型后跟as e/error 的形式来用于记录具体的异常类型,其中e/error获取异常信息。
例如下列python代码:
try: a = 1 b = 2 c = a * d print(c) except NameError as e: print(f"程序异常,异常原因是:{e}") c = a * b print(c)
运行结果如下,其中的name ‘d’ is not defined就是所记录的异常信息:
2、多个异常
可能代码中有多个异常,可通过将异常类一并放在except子句后或使用多个except子句。
例如下列python代码,这里except (TypeError, NameError) as error的含义是当程序中有对类型无效的操作(TypeError)或未声明/初始化对象(NameError)时输出异常信息:
try: def function(a, b): print(a, b) function(2, 3, 4) except (TypeError, NameError) as error: print(f"程序异常,异常原因是:{error}")
运行结果如下:
也可以分开写多个except子句,即当程序中有不同的异常时执行哪个子句。
例如下列python代码,程序中有对类型无效的操作时通过input()函数接收一个标准输入数据c并输出该数据,而当程序中有未声明/初始化对象的异常时输出记录的异常信息:
try: def function(a, b): a = b + c print(a) function(1, 2) except TypeError as error: print(f"程序异常,异常原因是:{error}") except NameError as error: print(f"程序异常,异常原因是:{error}") c = input("请输入变量c的值:") print(c)
运行结果如下,由于未声明变量c:
3、省略异常类
省略异常类即省略except子句后的异常类型,表明处理所有捕获到的程序异常。
例如下列python代码:
try: a = 1 b = 2 c = a + d print(c) except: print("捕获到异常!")
运行结果如下:
(二)try…except…else语句
在try…except语句后加一个else子句,该子句的内容即当try子句没有发生任何异常时执行的代码。
例如下列python代码,当程序有未声明/初始化对象的异常情况时输出提示,若无异常则输出a-b的值:
try: a = 1 b = 2 c = a + b print(c) except NameError: print("未声明/初始化对象!") else: c = a - b print(c)
运行结果如下:
(三)try…except…finally语句
try…except语句与finally子句一起运用时,表示无论是否捕获到异常,finally子句内的代码都要执行,比如在处理文件时就要用到finally子句,即用于关闭文件从而避免占用资源。
例如下列python代码,这里finally子句中不管是否有异常,该子句内的文件关闭file.close()都要执行:
try: file = open("file1.txt", mode="r", encoding="utf-8") file.write("123456789") except Exception as error: print(f"文件写入失败!原因是:{error}") finally: file.close() print("文件已被关闭!")
运行结果如下:
也可以通过with语句来释放文件,执行语句后with语句会关闭文件,若文件不能打开则也会关闭文件,格式如下:
with 上下文表达式 [as 资源对象] 语句
这里的上下文表达式返回一个上下文资源器对象,若指定了as子句,则将上下文资源管理器对象的__enter__()方法的返回值赋值给资源对象,另外要注意不是所有对象都可以使用with语句,只有支持上下文管理协议的对象才可以使用该语句。
三、抛出异常
捕获异常可以理解为程序有异常系统报错,另外我们可以通过相关的语句来使异常主动抛出。
(一)raise语句
1、异常类型抛出异常
在raise语句后跟异常类型,即可以通过使用异常类型的名称从而抛出异常。
例如下列python代码,通过使用raise语句抛出OverflowError异常,该异常类型表示数值运算超出最大限制:
raise OverflowError
运行结果如下:
2、异常对象抛出异常
例如下列python代码,创建了一个OverflowError类的obj_error对象并通过raise语句抛出对象:
obj_error = OverflowError() raise obj_error
运行结果如下:
3、由异常抛出异常
通过单用raise关键字可以重新抛出发生的异常。
例如下列python代码:
try: print(a) except NameError as error: print(f"文件写入失败!原因是:{error}") raise
运行结果如下:
(二)assert断言语句
assert断言语句用于判断一个表达式是否为真,若为假则抛出AssertionError异常,格式如下,其中表达式是判断的对象,参数通常是一个自定义的描述异常具体信息的字符串:
assert 表达式[,参数]
例如下列python代码,1<-1表达式为假所以程序抛出AssertionError异常:
a = 1 b = -1 assert a < b
运行结果如下:
四、自定义异常
虽然python中定义了很多的异常类型,但我们也可以自定义异常,即通过创建一个类,让其继承Exception类或其它类。
例如下列python代码,首先自定义异常my_error类,在其类的构造方法中调用基类Exception的__init__方法并将异常信息作为参数
class my_error(Exception): def __init__(self, error="格式错误"): super().__init__(error) def f_main(): file_name = input("请输入文件名称:") try: if file_name.split(".")[1] in ["txt", "doc"]: print("文件名称无异常!") else: raise my_error() except Exception as error: print(f"程序异常,异常原因是:{error}") f_main()
运行结果如下: