目录
[else 和 finally关键字](#else 和 finally关键字)
1.捕获异常与处理
错误和异常的区别:错误每次运行程序都会出现,而异常只有在触发某些条件时才会出现
异常处理语法
python
try:
<body>
except <ExceptionType>:
<handler>
异常处理的语法是将可能会抛出异常的代码包裹在try语句中。在这里,<body>包含了可能抛出异常的代码。当一个异常出现时,<body>中剩余代码被跳过。如果该异常匹配一个异常类型,那么<handler>将被执行。
如果一个异常出现但是异常类型不匹配 except 子句中的异常名,那么这是一个未处理异常且终止程序显示错误信息。
常见的系统内置的异常
else 和 finally关键字
一个try语句可以有多个except子句来处理不同的异常。这个语句可以选择else或者finally语句,语法如下:
python
try:
<body>
except <ExceptionType1>:
<handler1>
except <ExceptionType2>:
<handler2>
...
except <ExceptionTypeN>:
<handlerN>
except:
<handler>
else:
<process_else>
finally:
<process_finally>
多个except子句与elif语句类似。当一个异常出现时,它会顺序检查是否匹配except子句中的异常。如果找到一个异常,那么该except子句的处理器将被执行,而其它except子句将被忽略。如果异常在最后【except:】子句都没有匹配上,那么将执行【except:】中的处理器。
一个try语句可以有一个可选择的else语句,如果try中没有抛出异常,将会执行else块。
一个try语句可以有一个可选择的finally语句,用来定义收尾动作,无论何种情况都会执行块。
注意只要异常未被捕获,无论是否有 finally 等语句,都会终止程序并显示错误信息。
代码示例
python
try:
file = open(r"\email.txt", "rb")
data = file.readline().decode("ANSI")
mylist = data.split("----")
num = eval(mylist[0]) # 转化失败
print(num, end="")
file.close()
except FileNotFoundError:
print("文件没有找到")
except KeyError:
print("索引越界")
except NameError:
print("转换失败")
except:
print("这是其它类型的异常")
else:
print("没有异常会执行这里")
finally:
print("有没有异常都要执行执行这一句")
2.抛出异常
使用 raise 关键字设置抛出异常
抛出异常可以设置在函数中,也可以设置在类中
既可以抛出一个异常名,也可以抛出一个自定义的异常类
示例1
这里 ExceptionClass("Something is wrong")表示用异常类 ExceptionClass 创建了一个对象
示例2
示例3
示例代码
python
def func(value1, value2):
if value2 == 0:
raise Exception("不允许,被零除")
return (value1 + value2) / value2
func(1, 0)
运行报错
bash
Traceback (most recent call last):
File "D:\projects\test\main.py", line 9, in <module>
func(1, 0)
File "D:\projects\test\main.py", line 5, in func
raise Exception("不允许,被零除")
Exception: 不允许,被零除
3.函数嵌套时异常捕获机制
如果当前函数没有捕获一个异常,这个异常将会被传递给它的调用者,这个过程一直重复到这个异常被捕获,如果最终都没有被捕获,则会终止程序并显示错误信息。
python
def func1(value1, value2):
if value2 == 0:
raise Exception("不允许,被零除")
return (value1 + value2) / value2
def func2(data: list):
for i in range(len(data)-1):
ret = func1(data[i], data[i+1])
print(data[i], data[i+1], "->", ret)
def main1():
try:
value_list = [1, 2, 0, 5, 7, 0, 3]
func2(value_list)
except:
print("出现异常")
def main2():
value_list = [1, 2, 0, 5, 7, 0, 3]
func2(value_list)
main1()
# main2()
4.访问异常对象
一个异常被包裹在一个对象中,为了抛出一个异常,首先需要创建一个异常对象,然后使用raise关键字抛出。这个异常对象能够从except子句中访问吗?答案是肯定的。语法如下:
python
try:
<body>
except ExceptionType as ex:
<handler>
print(ex)
示例代码
python
try:
n = eval(input("请输入一个数:"))
print("这个数是", n)
except NameError as ex:
print("NameError:", ex)
运行示例
bash
请输入一个数:abc
NameError: name 'abc' is not defined
注意:print(ex)等价于是print(ex.str())。
5.自定义异常类
可以通过 BaseException 类或者 BaseException 类的子类来定义一个自定制异常类。
示例代码
python
class SizeException(Exception): # 继承关系
def __init__(self, error_value): # 错误代码初始化
self.value = error_value
def __str__(self): # 错误信息
error_info = f"错误的参数值:{str(self.value)}"
return error_info
class Box:
def __init__(self, x, y, z):
if x > 10:
raise SizeException("big") # 触发一个匿名对象表示错误
elif x < 2:
raise SizeException("small")
if y > 10 or y < 2:
raise 2 # 报错,提示 2,但无法处理
# 自定义异常只能处理类型,像整数这些不能处理)
if z > 10 or z < 2:
raise 3
self.x = x
self.y = y
self.z = z
try:
b1 = Box(1, 4, 5)
except SizeException as e: # as 创建了该异常类型的对象,e 对象名称
print("SizeException:", e)
print(e.value)
print("---------------------------------")
try:
b1 = Box(5, 100, 5)
except Exception as e:
print("Exception:", e)
运行结果
bash
SizeException: 错误的参数值:small
small
---------------------------------
Exception: exceptions must derive from BaseException
6.assert关键字
在python中,assert关键字用于在代码中设置检查点(checkpoints),这些检查点用于验证程序中的某个条件是否为真。如果条件为假(即评估为False),assert将引发一个AssertionError异常。这通常用于调试目的,以确保在程序的某些关键点满足特定的条件。
assert语句的基本语法是:
python
assert expression[, arguments]
expression 是要评估的表达式。
如果提供了 arguments,它们将在 AssertionError 异常的消息中显示。
如果 expression 为真(即评估为True),则 assert 语句什么也不做。但是,如果 expression 为假,则会引发一个 AssertionError。
以下是一个简单的例子:
python
def divide(a, b):
assert b != 0, "你妹的脑子进水了传 0 干毛线"
return a / b
# 正常工作
print(divide(10, 2)) # 输出: 5.0
# 引发 AssertionError
print(divide(10, 0)) # AssertionError: 你妹的脑子进水了传 0 干毛线
在上面的例子中,assert 语句用于检查除数 b 是否为零。如果为零,则引发一个 AssertionError,并显示提供的消息 "你妹的脑子进水了传 0 干毛线"。
尽管 assert 在调试和测试时非常有用,但通常不建议在生产环境的代码中过度依赖它,因为 assert 语句可以在运行时通过传递 -O(优化)选项给Python解释器来禁用。在生产环境中,更好的做法是使用异常处理和其他控制流语句来处理可能的错误情况。
end