一、文件
1.1 打开
1.1.1 open()
file = open(文件名, [打开模式], [读写文件的缓冲模式], [编码方式])
文件名:如果要打开的文件和当前文件在同一目录下,可直接用文件名,否则需要指定完整路径;
打开模式:可选参数,可以选择只读,只写,读写模式,默认为只读(r),需要用引号括起来;
缓冲模式:可选参数,表示读写文件的缓冲模式,0表示不缓存,1表示缓存,大于1表示缓冲区的大小,默认缓存;
编码方式:可选参数,编码方式默认是GBK,如果需要打开UTF-8编码的文件,需要写明,指定编码方式encoding='utf-8'。
1.1.2 打开模式
类别 | 普通格式 | 以二进制格式打开 | 区分 | 能否创建新文件 | |
读 | 只读 | r | rb | 只能读,不能写。 指针在文件开头 | |
写 | 覆盖 | w | wb | 可以写。区别: w是覆盖原内容;a是保留原内容,在末尾追加 | 能 |
追加 | a | ab | 能 | ||
读写 | 覆盖 | w+ | wb+ | 可以读写。区别: w+是覆盖原有内容;a+是保留原内容,在末尾追加;r+是在指针处写入内容,会覆盖指针后的内容,如果指针在开头,会覆盖整个文件内容 | 能 |
追加 | a+ | ab+ | 能 | ||
写入 | r+ | rb+ |
总结一下:
只读用r,创建文件用w, a;
覆盖原内容用w,不覆盖用a;
只读只写不带+,读写末尾带+;
以二进制形式打开时末尾带b,二进制常用于打开非文本文件,如图片、音频、视频等
1.1.3 创建
w, a, w+, a+都可以创造文件。
举个例子:
print('打开一个文件,如果不存在时就创建它')
f1 = open('123.tet', 'a+', encoding='utf-8')
# 创建并打开123.txt,并拥有读取和写入权限
f2 = open('123.png', 'rb')
# 以二进制形式打开非文本文件
1.1.4 关闭
之前我们打开文件是,file = open(filename, mode),这个模式打开的文件不能自动关闭,需要手动关闭文件。
关闭文件的语句:file.close()
file = open('123.txt','w+') # 打开文件
"""中间进行操作"""
file.close() # 关闭文件
1.1.5 with语句
如果我们担心忘记关闭文件,或者打开文件时抛出异常无法关闭,可以使用with语句。
with用途:
with语句可以保证无论文件是否抛出异常,都能在with语句执行完后关闭打开的文件。
with用法:
with open(filename, mode) as file:
with语句
with语句可以指定打开文件后的一些操作,如果不想执行任何操作,可以用pass代替。例如:
with open('123.txt', 'w') as f3: # 指定变量f3,将打开文件的结果保存进变量f3
pass
以上,打开文件的相关操作就告一段落了。
1.2 写入
1.2.1 写入一条
file.write(string)
string为要写入的字符串
1.2.2 写入多条
file.writelines(list)
list为要写入的字符串列表,每个列表元素都是要写入的字符串;
with open('123.txt', 'w+') as f3:
f3.write('春眠不觉晓,\n') # 单句写入需要添加换行符才会换行
f3.write('处处闻啼鸟。\n')
f3.writelines(['夜来风雨声,', '花落知多少。']) # 一次写入多行
with open('123.txt', 'r') as f3:
r = f3.readlines()
print(r) # 读取文件的全部行
# ['春眠不觉晓,\n', '处处闻啼鸟。\n', '夜来风雨声,花落知多少。']
1.3 读取
1.3.1 读取字符和移动指针
1、读取字符
file.read(size)
① size为要读取的字符长度,不指定的话会读取全部文件;
② 从指针位置读取指定个数字符,如果不移动指针,默认从头读取
③ 只适用于用'r'和'r+'打开,否则会抛出异常
④ read()函数中,汉字、字母、数字均占一个字符,不同于seek()函数指标移动的字符计算
2、移动指针
file.seek(offset,[whence])
① offset为要移动的字符数,按汉字占2字符,英文字母和数字占1字符计算
② whence为指标开始移动的位置,0是从头开始计算,1是从当前位置,2是从文件尾开始计算,默认为0
with open('123.txt', 'w+') as f3: # 指定变量f3,将打开文件的结果保存进变量f3
f3.write('春眠不觉晓,')
f3.write('处处闻啼鸟。')
f3.writelines(['夜来风雨声,', '花落知多少。'])
with open('123.txt', 'r') as f3:
r = f3.read(5)
print(r) # 春眠不觉晓
f3.seek(12) # 移动指针,从头移动,移动12个字符,汉字占2个,汉字标点占2个
r = f3.read(5) # 在新的指针位置读取5个字符
print(r) # 处处闻啼鸟
1.3.2 读取一行
file.readline()
① 有时,我们避免要读取的文件过大,会使用逐行读取的方法,这时我们可以使用readline()函数每次读取一行。readline(),从指针后读取一行。
② 同样,只适用于用'r'和'r+'打开。
1.3.3 读取全部行
file.readlines()
① 从指针后读取全部行,输出结果为一个字符串列表,每行是列表的一个元素。
② 遍历后能获得全部字符串文本。
与file.read()的区别:
file.read()输出结果为文本,file.readlines()输出结果为字符串列表。
# 读取一行
with open('123.txt', 'r') as f3:
r = f3.readline()
print(r) # 春眠不觉晓,
# 读取全部(指针后的全部)
r = f3.readlines()
print(r) # ['处处闻啼鸟。\n', '夜来风雨声,\n', '花落知多少。']
# 用read读取全部
with open('123.txt', 'r') as f3:
r = f3.read()
print(r) # 春眠不觉晓,
# 处处闻啼鸟。
# 夜来风雨声,
# 花落知多少。
1.3.4 for-in循环
for in 循环可逐行输出以'r''r+'模式打开的只读文件,效果等同于使用file.readline()多次读取文件。
with open('123.txt', 'r') as f:
# print(f)
for line in f:
print(line, end='')
time.sleep(0.5)
""" 逐行输出
春眠不觉晓,
处处闻啼鸟。
夜来风雨声,
花落知多少。
"""
二、JSON
2.1 JSON是什么
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,以纯文本格式存储和表示数据,完全独立于语言。
因为其易于阅读和编写,使其成为一种流行的数据交换格式。常用于(摘自百度AI知道):
-
数据交换:JSON文件经常用于在不同的系统、应用程序或服务之间交换数据。由于其易于阅读和编写的特性,它成为了一种流行的数据交换格式。
-
数据存储:JSON文件也可以作为轻量级的数据存储方式。它们可以存储各种类型的数据,包括字符串、数字、对象(键值对集合)、数组等。这使得JSON文件成为缓存数据或存储配置信息的理想选择。
-
配置文件:许多应用程序使用JSON文件作为配置文件,因为它们提供了灵活且易于解析的结构来存储设置和参数。
-
API响应:在Web开发中,许多RESTful API使用JSON作为响应格式。当客户端请求数据时,服务器通常会返回一个JSON格式的响应,其中包含所需的数据。
-
跨平台兼容性:由于JSON是基于文本的,它可以在任何支持文本处理的环境中使用,无论操作系统或编程语言如何。这使得JSON成为一种跨平台的、可移植的数据表示形式。
-
人类可读性:与二进制数据格式相比,JSON文件具有更好的可读性。它们使用标准的文本格式,因此可以轻松地用文本编辑器打开和编辑。
2.2 序列化
序列化是将数据结构或者对象状态转化为可储存,可传输的形式(如JSON),在这期间,对象将其当前状态写入到临时或持久性存储区。后续可以通过从存储区中读取数据或反序列化,重新创建该对象。
序列化常用于数据的存储和传输。如将对象保存到硬盘,或者通过网络发送对象。
2.2.1 dump和dumps
dump(Python对象名,存储json文件的变量):将Python对象按JSON格式序列化到文件中
dumps(Python对象名):将Python对象按JSON格式序列化为字符串
区别:因为dumps是返回序列化后的字符串,而dump是将序列化后的数据写入文件,所以,当需要将对象转换为字符串进行操作时,常用dumps序列化对象(如传输时);当需要存储对象时,常用dump序列化对象。
应用:
创建和写入文件
# JSON文件
import json
def main():
# 储存了张三的字典
dict1 = {
'name': '张三',
'age': 18,
'hobby': 'reading',
'school': 'QH',
'major': ['Finance', 'Mathematics']
}
# 创建一个普通文件,保存数据
try:
with open('ordinary.txt', 'w+', encoding='utf-8') as txt:
txt.write(str(dict1))
except FileNotFoundError:
print('无法打开指定的文件')
except IOError:
print('读写文件时发生错误')
else:
print('成功将%s的信息写入了txt文件' % dict1['name']) # 成功将张三的信息写入了txt文件
finally:
print('执行了一次写入txt文件的操作,文件名:ordinary.txt\n') # 执行了一次写入txt文件的操作,文件名:ordinary.txt
# 创建一个JSON文件,保存数据
try:
with open('json.json', 'w+', encoding='utf-=8') as js:
json.dump(dict1, js)
except FileNotFoundError:
print('无法打开指定的文件')
except IOError:
print('读写文件时发生错误')
except LookupError:
print('指定了未知的编码')
except UnicodeDecodeError:
print('读取文件时解码错误')
else:
print('成功将%s的信息写入了json文件' % dict1['name']) # 成功将张三的信息写入了json文件
finally:
print('执行了一次写入json文件的操作,文件名:json.json\n') # 执行了一次写入json文件的操作,文件名:json.json
# 将张三信息转化为JSON字符串,方便传输
json_data = json.dumps(dict1)
print(json_data) # {"name": "\u5f20\u4e09", "age": 18, "hobby": "reading", "school": "QH", "major": ["Finance", "Mathematics"]}
if __name__ == '__main__':
main()
在JSON文件中追加信息 :
import json
def main():
"""额外写入李四信息"""
# 李四信息
dict2 = {
'name': '李四',
'age': '18',
'hobby': 'hiking',
'school': 'BD',
'major': ['Politics', 'History']
}
try:
with open('json.json', 'a+', encoding='utf-8') as js:
json.dump(dict2, js)
except FileNotFoundError:
print('打开文件时遇到问题')
except IOError:
print('读写文件时遇到问题')
else:
print('成功将%s的信息写入了json文件:json.json' % dict2['name']) # 成功将李四的信息写入了json文件:json.json
finally:
print('执行了一次追加json文件的操作,文件名:json.json') # 执行了一次追加json文件的操作,文件名:json.json
if __name__ == '__main__':
main()
2.2.2 可以序列化JSON格式的Python对象
类型 | Python | JSON |
字典 | dict | object |
列表 | list | array(数组) |
元组 | tuple | array |
整数/浮点数 | int/float | number |
布尔值 | True/False | true/false |
None | None | null |
- 字典是Python中最常用的数据类型之一,也是JSON格式的主要表示形式。
- 元组本身不能被直接序列化为JSON,但可以将其先转换为列表,再序列化。
- 数组(array)是JSON格式中的一个特定类型,是由一系列的值(字符串、数字、对象、数组等)组成的集合,这些值由逗号分隔,并用方括号包围。类似Python中的列表(list)。
- 在JSON格式中,所有的字符串必须使用双引号(")。单引号(')或未引用的字符串在JSON中都是无效的。这是JSON规范的一个明确要求。
2.3 反序列化
反序列化则是从序列化表示形式(如JSON)中提取对象的过程。在反序列化期间,根据序列化的数据重新构造对象。
2.3.1 load和loads
load:将存储JSON数据的文件反序列化为Python对象
loads:将JSON字符串反序列化为Python对象
应用:
import json
dict1 = {
'name': '张三',
'age': 18,
'hobby': 'reading',
'school': 'QH',
'major': ['Finance', 'Mathematics']
}
# 转化为JSON文件并保存
with open('json.json', 'w+', encoding='utf-8') as js:
json.dump(dict1, js)
# 重新以阅读模式打开并读取
with open('json.json', 'r', encoding='utf-8') as js:
read = js.read()
print('序列化为JSON格式的字典:', read)
# 反序列化JSON文件
with open('json.json', 'r', encoding='utf-8') as js:
info = json.load(js) # 反序列化
print('文件的反序列化:', info)
# 序列化为字符串
data = json.dumps(info)
print('数据序列化为JSON字符串', data)
# JSON字符串反序列化
info2 = json.loads(data)
print('字符串的反序列化:', info2)
三、练习
3.1 将1-9999之间的质数分别写入三个文件中
"""
将1-9999之间的质数分别写入三个文件中
质数,只能被1和它本身整除的数,1不是质数
"""
def is_prime(i):
"""判断i是否是素数"""
prime = True
if i == 1:
prime = False
if i > 1:
for j in range(2, int(i ** 0.5) + 1):
if i % j == 0:
prime = False
break
return prime
def prime_numbers(a, b):
"""寻找a,b之间的素数,不含b"""
list1 = []
for i in range(a, b):
if is_prime(i):
list1.append(i)
return list1
def num_str(array, sep):
"""
提供一个将保存int/float数据的列表/元组中元素转化为str的函数,
并指定元素遍历后的分隔符,输出结果统一为列表。
"""
new_list = []
for i in array:
if isinstance(i, (int, float)): # 使用isinstance检查类型,同样可以用于检查对象是否属于某个类
item = str(i) + sep
new_list.append(item)
return new_list
def file_write(filename, a, b):
"""定义一个可以写入质数的函数"""
try:
with open(filename, 'w+', encoding='utf-8') as file:
data = prime_numbers(a, b)
data_str = num_str(data, ' ')
for item in data_str:
file.write(item)
except IOError:
print('读写文件发生错误')
else:
print('成功完成%d-%d之间质数的写入,保存在:%s' % (a, b-1, filename))
def file_read(filename):
"""定义一个输入文件名即可读取文件的函数,默认以‘r’模式打开"""
with open(filename, 'r', encoding='utf-8') as file:
read = file.readlines()
print('%s的内容是:\n%s' % (filename, read))
if __name__ == '__main__':
file_write('1-99.txt', 1, 100)
file_write('100-999.txt', 100, 1000)
file_write('1000-9999.txt', 1000, 10000)
file_read('1-99.txt')
file_read('100-999.txt')
file_read('1000-9999.txt')
欢迎小伙伴指正~