引言
python小程序之文件操作的输出指定格式数据以及异常捕获
文章目录
- 引言
- 一、文件操作之输出指定格式JSON
- 1.1 题目
- 1.2 代码
- 1.3 代码解释
- 1.3.1 总结
- 二、异常
- 2.1 概念
- 2.1.1 基本语法
- 2.1.1.1 `try...except`
- 2.1.1.2 `try...except...else`
- 2.1.1.3 `try...except...finally`
- 2.1.1.4 `try...except...else...finally`
- 2.1.2 捕获多个异常
- 2.1.3 捕获所有异常
- 2.1.4 抛出异常
- 2.1.5 自定义异常
- 2.1.6 总结
- 2.2 代码
- 2.2.1 try...except
- 2.2.2 try、except、else、finally完全版
- 2.2.3 捕获多个指定类型的异常
- 2.3 代码解释
- 2.3.1 try、except、else、finally完全版
- 2.3.2 捕获多个指定类型的异常
- 三、思考
- 3.1 输出指定格式JSON
- 3.2 异常
- 3.3 异常的传递
- 3.3.1 概念
- 3.3.2 代码实例
- 3.3.3 总结
一、文件操作之输出指定格式JSON
1.1 题目
某网站的测试数据如下 data.json, 需求,提取 json ⽂件中的⽤户名,密码和预期结果, 组成如下格式: [(), (), ()] (⾃动化参数化需要的数据格式)
1.2 代码
import json
def read_data():
data = []
with open('data.json', 'r', encoding='utf-8') as f:
info = json.load(f)
# print(info)
for i in info:
data.append((i.get('username'), i.get('password'), i.get('expect')))
return data
print(read_data())
输出结果:
1.3 代码解释
这段代码定义了一个函数
read_data
,该函数从一个名为data.json
的 JSON 文件中读取数据,并将每个条目的特定字段(username
,password
,expect
)提取出来,存储在一个列表中。最后,它打印出这个列表
-
导入
json
模块:import json
导入 Python 的
json
模块,用于处理 JSON 数据 -
定义
read_data
函数:def read_data():
定义一个名为
read_data
的函数,该函数没有参数 -
初始化空列表
data
:data = []
创建一个空列表
data
,用于存储从 JSON 文件中提取的数据 -
打开并读取 JSON 文件:
with open('data.json', 'r', encoding='utf-8') as f: info = json.load(f)
- 使用
open
函数以只读模式 ('r'
) 和指定编码 (encoding='utf-8'
) 打开data.json
文件 - 使用
json.load(f)
方法将文件内容解析为 Python 对象(通常是列表或字典),并将结果存储在变量info
中
- 使用
-
遍历
info
并提取特定字段:for i in info: data.append((i.get('username'), i.get('password'), i.get('expect')))
- 遍历
info
列表中的每个元素i
- 使用
i.get('username')
、i.get('password')
和i.get('expect')
分别获取每个元素中的username
、password
和expect
字段的值 - 将这三个值作为一个元组添加到
data
列表中
- 遍历
-
返回
data
列表:return data
返回包含所有提取数据的
data
列表 -
调用
read_data
函数并打印结果:print(read_data())
调用
read_data
函数,并打印其返回的结果
1.3.1 总结
通过这种方式,可以轻松地从 JSON 文件中提取特定字段的值,并将它们存储在一个列表中
二、异常
2.1 概念
在python 中,异常处理是一种重要的编程机制,它允许优雅地处理程序运行时可能出现的错误。Python 提供了
try
、except
、else
和finally
语句来实现异常处理
2.1.1 基本语法
2.1.1.1 try...except
这是最基本的异常处理结构。try
块中包含可能引发异常的代码,而 except
块则用来捕获并处理这些异常
try:
# 可能会抛出异常的代码
x = 1 / 0
except ZeroDivisionError as e:
# 捕获并处理特定异常
print(f"除零错误: {e}")
2.1.1.2 try...except...else
如果 try
块中的代码没有引发任何异常,则执行 else
块中的代码
try:
x = 1 / 1 # 不会引发异常
except ZeroDivisionError as e:
print(f"除零错误: {e}")
else:
print("没有发生异常")
2.1.1.3 try...except...finally
无论是否发生异常,finally
块中的代码都会被执行。这通常用于释放资源,如关闭文件或网络连接
try:
f = open("file.txt", "r")
content = f.read()
except FileNotFoundError as e:
print(f"文件未找到: {e}")
finally:
f.close()
print("文件已关闭")
2.1.1.4 try...except...else...finally
这是一个完整的异常处理结构,结合了上述所有部分
try:
f = open("file.txt", "r")
content = f.read()
except FileNotFoundError as e:
print(f"文件未找到: {e}")
else:
print(content)
finally:
f.close()
print("文件已关闭")
2.1.2 捕获多个异常
可以在一个 except
块中捕获多种类型的异常,或者使用多个 except
块分别处理不同类型的异常
try:
x = int(input("请输入一个整数: "))
y = 10 / x
except ValueError as e:
print(f"输入无效: {e}")
except ZeroDivisionError as e:
print(f"不能除以零: {e}")
2.1.3 捕获所有异常
如果想要捕获所有类型的异常,可以使用不带任何参数的 except
语句。但这样做通常是不推荐的,因为它可能会隐藏潜在的问题
try:
x = 1 / 0
except Exception as e:
print(f"发生了未知错误: {e}")
2.1.4 抛出异常
可以使用 raise
语句手动抛出异常。这通常用于表示某些条件不满足时的逻辑错误
def check_age(age):
if age < 0:
raise ValueError("年龄不能为负数")
elif age > 120:
raise ValueError("年龄太大,不合理")
else:
print(f"年龄是: {age}")
try:
check_age(-5)
except ValueError as e:
print(e)
2.1.5 自定义异常
可以通过继承内置的 Exception
类来创建自定义异常类
class MyCustomError(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)
try:
raise MyCustomError("这是一个自定义异常")
except MyCustomError as e:
print(f"捕获到自定义异常: {e}")
2.1.6 总结
通过合理使用这些异常处理机制,你可以编写更加健壮和用户友好的 Python 程序
2.2 代码
2.2.1 try…except
try:
num = input('请输⼊数字:')
num = int(num)
print(num)
except:
print('请输⼊正确的数字')
print('后续其他的代码,可以继续执⾏')
输出结果:
2.2.2 try、except、else、finally完全版
try:
num = input('请输⼊数字:')
num = int(num)
print(num)
a = 10 / num
print(f'a: {a}')
except Exception as e:
print(f"错误信息为: {e}")
else:
print('没有发生异常我会执行')
finally:
print('不管有没有发生异常,我都会执行')
输出结果(未发生异常):
输出结果(发生异常):
2.2.3 捕获多个指定类型的异常
try:
num = input('请输⼊数字:')
num = int(num)
print(num)
a = 10 / num
print(f'a: {a}')
except ValueError:
print('发生了异常, 请输入正确的数字...')
except ZeroDivisionError:
print('除数不能为 0')
输出结果(num格式不对,例如不是数字):
输出结果(num为0):
2.3 代码解释
2.3.1 try、except、else、finally完全版
这段代码是一个简单的 Python 程序,用于演示如何处理可能出现的异常
try:
- 开始一个 try 块,在这个块中尝试执行可能抛出异常的代码num = input('请输⼊数字:')
- 请求用户输入一个数字,并将该输入存储在变量num
中。这里得到的是字符串类型的值num = int(num)
- 尝试将用户输入的字符串转换成整数。如果用户没有输入有效的整数,则这行代码会引发ValueError
异常print(num)
- 如果上面的转换成功了,打印转换后的整数num
a = 10 / num
- 计算 10 除以num
的结果,并将结果存入变量a
。如果num
是 0,那么这里将会产生ZeroDivisionError
异常,因为除数不能为零print(f'a: {a}')
- 打印变量a
的值
接下来是异常处理部分:
except Exception as e:
- 如果在 try 块中的任何代码引发了异常,那么程序流程将跳转到 except 块。Exception
是所有内置非系统退出异常的基类,所以它能捕捉大多数常见的异常。as e
允许我们将异常对象赋给变量e
,这样我们可以在 except 块中使用它print(f"错误信息为: {e}")
- 使用 f-string 格式化输出异常信息。{e}
会被异常对象e
的字符串表示所替换
然后是正常执行流程的部分:
else:
- 如果 try 块没有抛出任何异常,那么 else 块将会被执行print('没有发生异常我会执行')
- 打印一条消息,表明 try 块内的代码执行顺利,没有遇到任何异常
最后是不论是否发生异常都会执行的部分:
finally:
- finally 块总是会被执行,无论 try 块中的代码是否抛出异常或者是否执行了 except 或者 else 块print('不管有没有发生异常,我都会执行')
- 打印一条消息,表明 finally 块被触发
综上所述,这段代码的主要目的是让用户输入一个数字,然后计算 10 除以这个数字的结果。同时,它也通过 try-except-else-finally 结构来处理和报告潜在的运行时错误,如输入无效或除数为零的情况,并且确保某些清理工作(在这个例子中只是打印一条消息)始终会被执行
2.3.2 捕获多个指定类型的异常
这段python 代码使用了
try
和except
结构来处理用户输入数字时可能出现的两种特定类型的异常:ValueError
和ZeroDivisionError
try:
- 开始一个 try 块,尝试执行可能抛出异常的代码num = input('请输⼊数字:')
- 向用户请求输入,并将输入存储在变量num
中。这里得到的是字符串类型的数据num = int(num)
- 将用户输入的字符串尝试转换成整数。如果输入不是有效的整数(例如,用户输入了一个字母或符号),这行会引发ValueError
异常print(num)
- 如果转换成功,则打印转换后的整数num
a = 10 / num
- 计算 10 除以num
的结果,并将结果存入变量a
。如果num
是 0,那么这行会引发ZeroDivisionError
异常,因为不能除以零print(f'a: {a}')
- 打印变量a
的值
接下来是针对不同异常的处理部分:
-
except ValueError:
- 如果在 try 块中发生了ValueError
异常(即第3步中的转换失败),程序流程跳转到这个 except 块 -
print('发生了异常, 请输入正确的数字...')
- 输出一条消息给用户,提示他们输入了一个无效的数字 -
except ZeroDivisionError:
- 如果在 try 块中发生了ZeroDivisionError
异常(即第5步中的除数为0),程序流程跳转到这个 except 块 -
print('除数不能为 0')
- 输出一条消息给用户,告诉他们不能用0作为除数
这段代码通过分别捕捉
ValueError
和ZeroDivisionError
来提供更具体的错误信息,从而提高了用户体验。如果用户输入非数字字符,他们会收到一条关于输入正确数字的消息;如果用户试图用0做除数,他们会被告知这是不允许的。这样,用户可以清楚地知道他们的输入哪里出了问题,并且有机会纠正它
三、思考
3.1 输出指定格式JSON
- 导入
json
模块:用于处理 JSON 数据 - 定义
read_data
函数:该函数从data.json
文件中读取数据 - 初始化空列表
data
:用于存储提取的数据 - 打开并读取 JSON 文件:使用
open
和json.load
将 JSON 文件内容加载为 Python 对象 - 遍历
info
并提取特定字段:将username
、password
和expect
字段的值作为元组添加到data
列表 - 返回
data
列表:返回包含所有提取数据的列表 - 调用
read_data
函数并打印结果:调用read_data
函数,并打印其返回的结果
3.2 异常
try
:包含可能引发异常的代码except
:捕获并处理特定异常else
:如果没有异常发生,则执行的代码finally
:无论是否有异常发生,都会执行的代码raise
:手动抛出异常- 自定义异常:通过继承
Exception
类来创建自定义异常类
3.3 异常的传递
3.3.1 概念
异常传递是指在一个函数中抛出的异常没有被捕获,而是被传递给调用该函数的地方。如果调用者也没有处理这个异常,那么异常将继续向上层调用栈传递,直到被某个 except
块捕获或导致程序终止。在python中,异常传递是自动进行的。如果不使用 try...except
语句来捕获异常,那么异常就会从当前作用域向上传递到上一级调用者
3.3.2 代码实例
def divide(a, b):
return a / b # 如果 b 是 0,这里会抛出 ZeroDivisionError
def call_divide(x, y):
result = divide(x, y) # 如果 divide 抛出异常,这里不会处理它
print(f"Result: {result}")
try:
call_divide(10, 0) # 调用 call_divide 并传递可能引发异常的参数
except ZeroDivisionError as e:
print(f"Caught an exception: {e}")
在这个例子中,divide
函数尝试执行除法操作。如果 b
(也就是 y
)是 0,divide
将抛出一个 ZeroDivisionError
。由于 divide
函数内部没有 try...except
结构来捕获这个异常,所以异常会被传递给 call_divide
函数。同样地,call_divide
也没有捕获异常,因此异常继续向上抛出。最后,异常到达了最外层的 try...except
结构,在那里它被 except ZeroDivisionError
捕获,并打印出错误信息
3.3.3 总结
这种机制允许将错误处理逻辑集中在程序的适当位置,而不是分散在各个函数中。它也使得可以设计出更加模块化和可维护的代码。当异常发生时,可以通过检查调用栈来追踪异常是从哪里开始发生的