异常、文件操作
文章目录
一、文件的操作
文件操作,使用代码 来读写文件
1, Game案例,最高分不能保存的,可以将最高分保存到文件中,
2,自动化,测试数据在文件中保存的,从文件中读取测试数据,进行自动化代码的执行
1.1 文件的概念
文件:可以存储在长期存储设备(硬盘,U盘)上的一段数据即为文件
1,计算机只认识二进制数据(0和1)
2,所有的文件在计算机中存储的形式都是=进制即0和1 ,打开文件看到的是文字不是0和1,原因是打开文件的软件会自动的将二进制转换为文字
文件的分类(根据能否使用文本软件(记事本)打开文件):
--文本文件
--二进制文件
- 文本文件:可以使用记事本软件打开
- txt、py、md、json
- 二进制文件:不能使用 记事本软件打开
- 音频文件:MP3。。。
- 视频文件:MP4 。。。
- 图片:png、jpg、gif、exe
1.2 文件操作的步骤[重要]
1,打开文件 2,读、写文件 3,关闭文件(保存)
1.2.1 打开文件 open()【背、记忆】
open()函数默认以只读方式打开文件,并且返回文件对象
open(file, mode='r', encoding=None) # 将硬盘中的文件加载到内存中
- file: 表示要操作的文件的名字,可以使用相对路径和绝对路径
绝对路径,从根目录开始书写的路径 C:/ D:/
相对路径,从当前目录开始书写的路径 ./ ../
- mode: 打开文件的方式
r ,只读 打开, read , 默认模式。如果文件不存在,会报错
w ,只写 打开,write, 如果文件存在,会覆盖原文件;不存在,创建新文件
a ,追加 打开,append, 已存在,在文件的末尾写入新的内容;不存在,创建新文件进行写入
rb ,以二进制格式打开一个文件用于只读
wb ,以二进制格式打开一个文件只用于写入
- encoding: 编码格式,指 二进制数据 和 汉字 转换的规则的
utf-8(常用) :将一个汉字转换为 3 个字节的二进制
gbk:将一个汉字转换为 2 个字节的进制
返回值:文件对象,后续对文件的操作,都需要这个文件对象
1.2.2 关闭文件 close()
文件对象.close() # 关闭文件,如果是写文件,会自动保存,即将内存中的数据同步到硬盘中
1.2.3 读文件read()
变量 = 文件对象. read()
返回值:返回读取到文件内容,类型是字符串
# with open('a.txt',encoding='utf-8') as f:
# buf=f.read()
# print(buf)
f = open('a.txt',encoding='utf-8')
data = f.read()
print(data)
f.close()
1.2.4 写文件write()
文件对象. write()
参数:写入文件的内容,类型字符串
返回值:写入文件中的字符数,字符串的长度,一般不关注
# 1,打开文件
f = open('a.txt','w',encoding='utf-8')
# 2,读、写文件
f.write('坚持 ')
# 3,关闭文件(保存)
f.close()
1.2.5 文件打开的另一种写法(推荐)
with open(file, mode, encoding) as 变量: #变量 就是文件对象
pass
# 使用这种写法打开文件,会自动进行关闭,不用手动书写关闭的代码
# 出了 with 的缩进之后,文件就会自动关闭
with open('a.txt','a',encoding='utf-8') as f:
f.write('good study \n')
1.2.6 按行读取文件readline()
读取文件内容方法:
● 文件对象.readline() 方法可以一 次读取一行内容,方法执行后,会把文件指针移动到下一行,准备再次读取。返回读取的内容。
● read() 和 readline() 如果读到文件末尾,返回的都是 空字符串
with open('a.txt',encoding='utf-8') as f:
buf = f.readline()
print(buf) # 读取第一行的
buf1 = f.readline()
print(buf1) # 读取之后就不能再读了,所以输出的是第二行的
1.2.7 读取大文件
# with open('a.txt',encoding='utf-8') as f:
# while True:
# buf = f.readline() # 文件读完了,返回 空字符串
# if buf == "":
# break
# else:
# print(buf,end='')
with open('a.txt',encoding='utf-8') as f:
while True:
buf = f.readline() # 文件读完了,返回 空字符串
if buf: # 空字符串 是 False,非空字符串 是 True
print(buf,end='')
else:
break
1.2.8 打开文件的方式
r W a 称为是文本方式打开,适用于文本文件,会对二进制进行编码转换
rb wb ab 称为是二进制方式打开,可以打开文本文件和二进制文件,但是 二进制文件只能使用 二进制方式打开,同时,不能传递encoding 参数
with open('b.txt','rb') as f:
buf = f.read()
print(buf)
#b'\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88'
二 、 JSON操作
1,json 文件的本质也是文本文件,就可以直接使用read 和 write去进行操作
2, json 文件比较特殊,比较像 Python 中的字典和列表
3, json 文件使用比较频繁,按照 read 和 write 的操作,比较麻烦,专门的方法来操作 json 文件,可以直接得到 Python 中的列表和字典
2.1 JSON 介绍(特殊的文本文件)
2.1.1 介绍
1, json 文件,是一种基于文本,独立于语言的轻量级数据交换格式。
- 基于文本,文本文件,不包含 图片,视频等
- 独立于语言,不是某一种语言特有的, Python , Java , C++,
- 轻量级,相同的数据量,json 文件的占用的文件大小相对较小
- 数据交换格式,后端服务器 和前端页面 交换数据使用的格式
2,在自动化测试中经常用来存放测试数据,文件后缀名为: .json
提示:其他常见的数据源文件
格式: txt/excel/csv/xml
2.1.2 语法
1,json 中的数据类型
对象{} ----> Python 字典
数组[] ----> Python 列表
字符串,必须使用双引号 --》 str
数字类型 ---》 int, float
bool类型 ---》 True False
空值null ---》 None
2,json 文件,是一个对象或 者是数组,对象和数组可以相互嵌套
3, json 中的对象,是由键值对组成的,键必须是字符串类型,必须使用英文双引号
4,json 中的数据直接使用逗号隔开,最后一个数据后边不能加逗号
5,json 文件的后缀是 .json
2.1.3 文件的定义
我叫小明,我今年18岁,性别男,学校空,爱好听歌,吃饭,打豆豆,我的居住地址为国家中国,城市广州.
{
"name": "小明",
"age": 18,
"isMan": true,
"school": null,
"like": ["吃饭","听歌","打豆豆"],
"address": {
"country": "China",
"city": "广州"
}
}
2.1.4 读取json文件【重要】
1,可以直接使用 read 去读,但是 想要取到数据很麻烦
2,使用 专门的方法去读
2.1.导包 import json
2.2. json.load(文件对象) --->得到的是 列表 或者字典
# 读取 json文件
import json
with open('test.json',encoding='utf-8') as f:
buf = json.load(f)
print(type(buf)) #<class 'dict'>
print(buf)
# 姓名
print(buf.get('name'))
#城市
print(buf.get('address').get('city'))
# 爱好 使用下标处理列表
print(buf.get('like')[1])
# 学校
print(buf.get('school'))
练习:
我叫小明,我今年18岁,性别男,爱好听歌,吃饭,打豆豆,
我的居住地址为国家中国,城市广州. ---> 对象
我叫小红,我今年17岁,性别女,爱好听歌,学习,购物
我的居住地址为国家中国,城市北京,---> 对象
获取每个人的姓名,年龄性别,城市
# json
[
{
"name": "小明",
"age": 18,
"isMan": true,
"like": ["吃饭", "听歌", "打豆豆"],
"address": {
"country": "China",
"city": "广州"
}
},
{
"name": "小红",
"age": 17,
"isMan": false,
"like": ["学习", "听歌", "购物"],
"address": {
"country": "China",
"city": "北京"
}
}
]
import json
with open('test.json',encoding='utf-8') as f:
data_list = json.load(f)
for data in data_list:
# 扁平化代码
sex = "男" if data.get('isMan') else "女"
# if data.get('isMan'):
# sex = "男"
# else:
# sex = "女"
print(f"姓名:{data.get('name')},年龄:{data.get('age')}"
f"性别:{sex},城市:{data.get('address').get('city')}")
# 条件为True 执行的代码 if 判断条件 else 条件为 False 执行的代码
# a ='a' if 3 > 1 else 'b'
2.1.5写入数据操作【会用】
- 将Python中列表或者字典转换为json文件
- 导包import json
- 使用json. dump(Python中数据,文件对象)
#导入依赖包
import json
#要写入json文件的内容,可以是字典或列表
param = {'name': 'tom', 'age': 20}
#打开写模式
with open('data2.json', 'w', encoding='UTF-8') as f:
json.dump(param, f)
import json
info ={'name':'aaa','age':14}
with open('info1.json','w',encoding='utf-8') as f:
# json.dump(info,f) #
# json.dump(info,f,ensure_ascii=False) # 直接 显示 中文
json.dump(info, f, ensure_ascii=False,indent=2) # 缩进
三、异常
3.1概念
1,程序在运行时,如果Python解释器遇到到一个错误,则会停止程序的执行,并且提示一些错误信息,这就是异常.
2,程序停止执行并且提示错误信息这个动作,通常称之为:抛出(raise)异常
3.2 捕获异常【重要】
3.2.1 基本语法
try:
# 可能发生异常的代码
except : #可以捕获任意类型的异常
# 发生了异常执行的代码
# try: 尝试,下方编写要尝试代码,不确定是否能够正常执行的代码
# except:如果有异常捕获,下方编写捕获到异常,处理失败的代码
案例:
# 1.获取用户从键盘输入的数据
num = input('输入数字:')
try:
# 2.转换数据类型为整数
num = int(num)
# 3.数据转换类型正确时,输出数据内容
print(num)
except:
# 4.数据转换类型错误时,提示输入正确数据
print('请输入正确数据')
3.2.2 捕获指定类型的异常
发生的异常可能存在多种,针对不同类型的异常,解决处理的方案不一样
try:
可能发生异常的代码
except 异常类型1:
发了异常类型1 ,执行的代码
except 异常类型2:
发了异常类型2,执行的代码
except ...:
pass
# 注意:
#捕获特定异常类型,能够实现仅在特定异常类型出现时,代码再做对应的处理
#具体的异常类型可以先行从代码执行的报错信息中获取,在设置捕获异常操作
# 1.提示用户输入一个整数
# 2.使用8除以用户输入的整数并且输出
try:
num = int(input("输入一个数字"))
num1 = 8 / num
print(num1)
except ValueError:
print("输入的内容非数字,请重新输入")
except ZeroDivisionError:
print("不能输入数字0,请重新输入")
3.3.3 捕获未知类型的异常(使⽤最多)
try:
可能发生异常的代码
except Exception as 变量: # Exception 常见异常类的父类,变量异常对象,print()可以打印异常信息;变量可自定义
发生异常执行的代码
try:
num = int(input("输入一个数字"))
num1 = 8 / num
print(num1)
except Exception as e:
print(f"发生了异常,{e}")
3.3.4 异常捕获的完整结构
try:
可能发生异常的代码
except 异常类型:
发生了指定类型的异常执行的代码
except Exception as e:
发生了其他类型的异常执行的代码
else:
没有发生异常,会执行的代码
finally:
不管有没有发生异常,都会执行的代码
异常捕获完整语法案例
需求:
1.获取用户输入的数字
2.判断获取的数字是否整数
3.如果不是整数, 提示输入错误
4.如果是整数,则进一步判断是奇数还是偶数
5.最终提示: 程序运行结束
#方案一
使用异常捕获
#方案二
if判断
字符串.isdigit() # 判断数字是否是纯数字,是纯数字,返回True,不是返回False
# 方式一
# 1.获取用户输入的数字
num= input('输入数字:')
try:
# 2.判断获取的数字是否整数
num = int(num) #没有发生异常,说明是整数,如果发生异常,说明不是整数
except Exception as e :
# 3.如果不是整数, 提示输入错误
print("输入错误",e)
else:
# 4.如果是整数,则进一步判断是奇数还是偶数
if num % 2 ==0:
print('偶数')
else:
print('奇数')
# 5.最终提示: 程序运行结束
finally:
print('程序运行结束')
# 方式二
# 1.获取用户输入的数字
num = input('输入数字')
# 2.判断获取的数字是否整数
if num.isdigit():
# 如果是True,表示是整数
# 类型转换
num = int(num)
# 4.如果是整数,则进一步判断是奇数还是偶数
if num % 2 ==0:
print('偶数')
else:
print('奇数')
# 3.如果不是整数, 提示输入错误
else:
print('输入错误')
# 5.最终提示: 程序运行结束
print('程序运行结束')
3.3 异常的传递【知道】
1,异常传递是 Python 中已经实现好的功能, 不需要我们写代码实现
2,异常传递是指,在函数的嵌套调用过程中,如果发生了异常,没有进行捕获,会将这个异常传递到函数调用的地方,直到被捕获为止,如果一直没有捕获,才会报错,终止执行
# 1.定义函数demo1() 提示用户输入一个整数井且返回
def demo1():
num = int(input('请输入一个整数'))
return
# 2.定义函敞demo2() 调用demo1()
def demo2():
demo1()
# 3.在主程序中调用demo2()
if __name__ == '__main__':
# demo2() # 看下图所示
#1.保持代码整洁,不想增加大量的异常捕获代码
#2.需要让外部知道出现了异常
#3.异常比较严重,自己处理不了
# 可从外部捕获异常
try:
demo2()
except Exception as e :
print(e)
# 捕获结果
#请输入一个整数a
#invalid literal for int() with base 10: 'a'
3.4 抛出异常【知道】
1、 在执行代码的过程中,之所以会发生异常,终止代码执行,是因为代码执行遇到了 raise 关键字
2、 raise 关键字的作用,就是来抛出异常,让代码终止执行
3、 应用场景:自己书写代码模块,让别人使用,为了让别人按照你的规定使用你的代码,你就可以在他不满足你条件的情况下,使用 raise 抛出异常;还可以根据应用程序特有的业务需求主动抛出异常
Python中提供了一个Exception异常类
在开发时,如果满足特定业务需求时希望抛出异常,可以:
- 创建一个Exception类的对象
- 使用raise关键字抛出异常对象
#创建异常对象
ex= Exception(“异常描述信息”)
#抛出异常对象
raise ex
tools.py
def input_password():
"""输入密码的函数"""
pwd = input('请输入密码:')
if len(pwd) <8 :
# raise 异常
raise Exception('密码长度不足 8 位')
else:
return pwd
test.py
import tools
# pwd = tools.input_password()
# print(f"获取的密码是:{pwd}")
# 想要不报错就捕获异常
try:
pwd = tools.input_password()
print(f"获取的密码是:{pwd}")
except Exception as e:
print(e)