python第二十三节文件操作与路径操作(json,pickle,xml格式)

本文详细介绍了Python中文件操作的关键函数open(),如何使用不同的模式打开文件,以及with语句在文件操作中的优势。此外,还涵盖了路径操作相关的os模块功能,以及json、pickle和xml格式的序列化与反序列化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件操作

  • 从文件的编码方式来看,文件可以分为文本文件和二进制文件:
  • 文本文件:txt、html、json等; 二进制文件:图片、音频、视频等
  • 从计算机物理内存来看,所有文件都是二进制形式存放的
  • 因此文本文件也可以用二进制格式读取,而二进制文件是不能用文本格式读取的

open(file, mode=‘r’, encoding=None)

  • file:文件路径(相对路径或绝对路径)
  • mode:文件打开的模式,默认为 ‘r’ 模式
  • encoding:编码方式(只用在文本模式下),默认依赖平台,通常设置为 ‘UTF-8’
  • 打开 file 对应的文件,返回一个文件对象;如果该文件不能被打开,则引发OSError
from typing import Iterator


file = open(r'./t01.txt', mode='a')
file.write('hello world')
file.write('\nhello China')
file.write('\nhello Baby')
file.close()


file = open(r'./t01.txt')
print(isinstance(file, Iterator))
# print(list(file))
for i in file:
	print(i)

mode常用模式

模式描述
r以只读方式打开文件。文件的指针将会放在文件的开头。
w打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新的文件再写入。
a打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
+如果要以读写模式打开,加上 + 即可,比如:r+、w+、x+、a+
b默认为文本模式,如果要以二进制模式打开,加上 b 即可,比如:rb、rb+、wb、wb+

file常用对象方法:

file.read(size=-1)

  • 从 file 中读取至多 size 个字符并返回
  • 如果 size 为负值或 None,则读取至 EOF(End Of File)
with open(r"./t01.txt") as file:
	print(file.read(5))
	print(file.read(2))
	print(file.read())

file.write(s)

  • 将字符串 s 写入到流并返回写入的字符数
with open(r"./t01.txt", mode='a') as file:
	num = file.write('\nhello baby')
	print(num)

file.flush()

  • 刷新缓冲区,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要被动的等待缓冲区写入。一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用 flush() 方法
import time


file = open(r"./t01.txt", mode='a')
file.write('\n123456789')
time.sleep(5) # 文件需要等到关闭文件时才会把数据从缓冲区写入文件
file.close() # 关闭文件,自动刷新缓冲区,数据才写入文件


file = open(r"./t01.txt", mode='a')
file.write('\n123456789')
file.flush() # 刷新缓冲区,数据立刻写入文件
time.sleep(5)
file.close()

file.close()

  • 刷新缓冲区并关闭该文件。如果文件已经关闭,则此方法无效
  • 文件关闭后,对文件的任何操作(如:读取或写入)都会引发 ValueError
file = open(r'./t01.txt')
print(file.read())
file.close()
file.close() # 多次调用该方法,只有第一个调用才会生效
file.read() # 引发ValueError

file.writelines(lines)

  • lines:Iterable[str]
  • 向文件写入一个字符串序列,不会自动添加分隔符
tup = ("a\n", 'bc\n', "def")
with open(r"./t01.txt", mode="w") as file:
	file.writelines(tup)

file.readline(size=-1)

  • 从文件中读取并返回一行,如果指定了 size,将至多读取 size 个字符
with open("./t01.txt") as file:
print(file.readline())
print(file.readline(1))
print(file.readline())

file.readlines(hint=-1)

  • 从文件中读取并返回包含多行的列表
  • hint:默认为 -1,代表读取所有行(也可以指定读取的字符数,如果要读取的字符数超过一行,则按照两行读取,超过两行则按照三行读取,依次类推)
with open("./t01.txt") as file:
print(file.readlines())

with open("./t01.txt") as file:
print(file.readlines(11))

with语句

  • 这种写法如果在open之后close之前发生未知的异常,就不能确保打开的文件一定被正常关闭,这显然不是一个好的做法
file = open(r'./t01.txt', mode='w')
file.write('hello world')
...
...
file.close()
  • 所以可以使用下面这种写法,确保close一定会被执行
file = open(r'./t01.txt', mode='w')
try:
file.write('hello world')
...
...
finally:
file.close()
  • 用with语句将会是一种更加简洁、优雅的方式
with open(r'./t01.txt', mode='w') as file:
	file.write('hello world')
...
...

路径操作

os.getcwd()

  • 返回表示当前工作目录的字符串
import os

print(os.getcwd())

os.listdir(path)

  • 返回 path 指定的文件夹包含的文件或文件夹的名字的列表
import os

li = os.listdir(os.getcwd())
print(li)

os.makedirs(name, exist_ok=False)

  • 递归创建目录,并且还会自动创建到达最后一级目录所需要的中间目录
  • 如果 exist_ok 为 False (默认值),则如果目标目录已存在将引发 FileExistsError
import os

os.makedirs('./dir1/dir2/dir3')

os.path.basename(path)

  • 返回路径 path 最后一级的名称,通常用来返回文件名
import os

print(os.path.basename('./dir3/dir2/dir1/a.txt'))

os.path.dirname(path)

  • 返回路径 path 的目录名称
import os

print(os.path.dirname('./dir3/dir2/dir1/a.txt'))

os.path.split(path)

  • 把路径分割成 dirname 和 basename,返回一个元组
import os

print(os.path.split('./dir3/dir2/dir1/a.txt'))

os.path.splitext(path)

  • 把路径中的扩展名分割出来,返回一个元组
import os

print(os.path.splitext('./dir3/dir2/dir1/a.txt'))

os.path.exists(path)

  • path 路径存在则返回 True,不存在或失效则返回 False
import os

path = "./dir3/dir2/dir1/a.txt"
if os.path.exists(path):
	with open(path) as file:
		print(file.read())

os.path.isfile(path)

  • 判断路径是否为文件,返回 True 或 False
import os

print(os.path.isfile("./dir3/dir2/dir1/a.txt"))

os.path.isdir(path)

  • 判断路径是否为目录,返回 True 或 False
import os

print(os.path.isdir("./dir3/dir2/dir1"))

os.path.join(path, *paths)

  • 智能地拼接一个或多个路径部分
import os

print(os.path.join("./dir3/dir2", "dir1/a.txt"))

json格式

  • 字符串可以很轻松地写入文件并从文件中读取出来,而其他类型(比如:字典)复杂的数据会变得相当麻烦,因为 read() 方法返回字符串。
  • Python 允许你使用 json 格式,并提供了名为 json 的标准模块,它可以将 Python 数据结构转化为 json 格式的字符串(这个过程称之为序列化),也可以将 json 格式的字符串重建成Python 数据结构(这个过程称之为反序列化)。json 是一个文本序列化格式,可直观阅读。
  • 注意:json 中的键值对的键,永远是 str 类型。当一个对象被转化为 json 时,字典中所有的键都会被强制转换为字符串,导致当字典被转换为 json 然后转换回字典时可能和原来不相等。
import json


info = {'name': 'Tom', 'age': 18, 1: 'one'}
print(type(info), info)

with open("info.json", mode="w") as f:
	info_str = json.dumps(info) # 序列化
	print(type(info_str), info_str)
	f.write(info_str)
	
with open("info.json") as f:
	content = f.read()
	print(type(content), content)
	res = json.loads(content) # 反序列化
	print(type(res), res)
import json

info = {'name': 'Tom', 'age': 18, 1: 'one'}
with open("info.json", mode="w") as f:
	json.dump(info, f)
	
with open("info.json") as f:
	res = json.load(f)
	print(type(res), res)

pickle格式

  • pickle 是一个Python专用的二进制序列化格式,不可直观阅读。
import pickle

info = {'name': 'Tom', 'age': 18, 1: 'one'}
print(type(info), info)

with open("info.pickle", mode="wb") as f:
	info_byte = pickle.dumps(info)
	print(type(info_byte), info_byte)
	f.write(info_byte)
	
with open("info.pickle", mode="rb") as f:
	content = f.read()
	print(type(content), content)
	res = pickle.loads(content)
	print(type(res), res)

import pickle


info = {'name': 'Tom', 'age': 18, 1: 'one'}

with open("info.pickle", mode="wb") as f:
	pickle.dump(info, f)
	
with open("info.pickle", mode="rb") as f:
	res = pickle.load(f)
	print(type(res), res)

xml格式

XML文件格式是纯文本格式。XML文档的第一句是声明语句,紧接着声明后面建立的第一个元素是根元素(有且只有一个),其他元素都是这个根元素的子元素,每个XML元素包括一个开始标签,一个结束标签,以及两个标签之间的内容,每个元素还可以存在对应的属性。

import xml.etree.ElementTree as ET


# 将xml文档解析为元素树
tree = ET.parse(r"./json&xml/TestFile.xml")
# 返回该树的根元素, 即 <doc>
root = tree.getroot()

# 所有元素都是Element的实例对象
print(type(root) is ET.Element)

# findall: 根据路径找出所有匹配的子元素
for bndbox in root.findall('outputs/object/item/bndbox'):
	# Element对象调用实例属性
	print(bndbox.attrib)
	# findtext: 根据路径找出第一个匹配元素的文本内容
	print(bndbox.findtext('xmin'))
	print(bndbox.findtext('ymin'))
	print(bndbox.findtext('xmax'))
	print(bndbox.findtext('ymax'))
	# find: 根据路径找出第一个匹配元素
	# text: Element对象调用实例属性
	print(bndbox.find('xmin').text)
	print(bndbox.find('ymin').text)
	print(bndbox.find('xmax').text)
	print(bndbox.find('ymax').text)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙_尧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值