Python中级之文件操作
文件操作
【一】基本用法
在 Python 中,文件处理是常见的任务之一。以下是一些基本的文件处理操作和对应的 Python 语法:
打开文件:
使用 open()
函数来打开一个文件,可以指定文件名、打开模式和字符编码(可选)。
# 打开文件(只读模式)
file = open('example.txt', 'r', encoding='utf-8')
读取文件内容:
使用 read()
方法读取整个文件的内容,或者使用 readline()
方法逐行读取文件内容。
content = file.read()
# 逐行读取文件内容
line = file.readline()
while line:
print(line.strip()) # 去除换行符
line = file.readline()
写入文件内容:
使用 write()
方法将内容写入文件,需要在打开文件时选择写入模式('w' 或 'a')。
# 打开文件(写入模式)
file = open('example.txt', 'w', encoding='utf-8')
# 写入内容
file.write('Hello, World!\n')
file.write('Another line.')
关闭文件:
使用 close()
方法关闭文件,释放文件资源。
# 关闭文件
file.close()
with 语句:
使用 with
语句可以更安全地处理文件,确保在操作完成后自动关闭文件,即使发生异常也会正确关闭文件。
# 使用 with 语句
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read()
# 在这个块中,文件会被自动关闭,无论发生什么异常
# ...
以上是基本的文件处理操作,可以根据实际需求进行适当的调整。同时,还有其他文件处理方法和上下文管理器等特性可用于更复杂的文件操作场景。
【二】用法详细
【1】打开(with open)
# 注:此处文件可以直接打开是因为在同一路径下,如果不在同一路径需要指定路径名
# 如果不在同一路径下将会报错 # FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'
# 使用with open 可以简化文件打开后再关闭的流程
with open('文件名.后缀名','w/r/a',encoding='utf-8') as 句柄:
# with open('盘符:\路径名\文件名.后缀名','w/r/a',encoding='utf-8') as 句柄
打开文件后的代码块
# 如果单独使用open会较为麻烦
file = open('文件名.后缀名','w/r/a',encoding='utf-8')
file.write()/read()
file.close()
【2】文件的操作模式
(1) w/r/a
的参数
-
共三种模式文件的操作模式
- r:只读
- 文件存在文件内指针直接跳到文件开头
- 在文件不存在时则报错
FileNotFoundError
- w:覆盖写
- a:追加写,在光标后书写
- r:只读
-
w/r/a
参数并不是只能传一个参数,可以传多个w+
r+
a+
表示可读可写,一般不用可读可写模式t
文本模式(与w/r/a
之一结合使用)- t模式是默认模式,平常单独的
w/r/a
其实完整是wt/rt/at
- 读写文件都是以字符串为单位的
- 只能针对文本文件
- 必须指定encoding参数
- t模式是默认模式,平常单独的
b
二进制模式(与w/r/a
之一结合使用)- 读写文件都是以bytes/二进制为单位的
- 可以针对所有文件
- 一定不能指定encoding参数
(2)w
与a
的区别
- 在文件不关闭时,都是在光标后进行内容输入
- 当文件关闭时,
w
将使光标回到开头进行内容输入,将会覆盖掉原有的内容 - 当文件关闭时,
a
将跟在内容的结尾处进行内容输入,会与前文内容首尾相接
(3)路径的转义
-
当文件路径中出现与转义符冲突时,如
\t
\n
等 -
第一种使用
\\
进行转义符的取消转移,将其转义成斜杠的含义path = 'D:\python\text.txt' path = 'D:\python\\text.txt'
-
第二种使用
r+'字符串'
进行斜杠\
的声明path = 'D:\python\text.txt' path = r'D:\python\text.txt'
(4)写入内容的限制
-
t
模式下无论读出来的内容还是写入进去的内容,都应该以字符串为单位# 写入 list1 = [1,2,3] with open('01.txt', 'w', encoding='utf8') as fp: fp.write(list1) # TypeError: write() argument must be str, not list fp.write(str(list1)) # 需要强转才可以写入
with open('01.txt', 'r', encoding='utf8') as fp: print(fp.read()) print(type(fp.read())) # [1, 2, 3] # <class 'str'> # 哪怕再强转成列表也不可以 with open('01.txt', 'r', encoding='utf8') as fp: data = fp.read() print(data, type(data)) list2 = list(data) print(list2) # ['[', '1', ',', ' ', '2', ',', ' ', '3', ']']
-
b
模式下读写都是以二进制位单位with open('01.png', 'rb') as f1, open('02.png', 'w+b') as f2: data_old = f1.read() f2.write(data_old) data_new = f2.read() print(data_old, data_new)
# 常见二进制格式文件后缀: # .bin:通常用于存储计算机程序或数据的二进制文件,例如操作系统、应用软件和游戏等。 # .dmg:这是苹果公司Mac OS X操作系统中常用的磁盘映像文件格式,可以将多个文件打包成一个文件来方便传输和安装。 # .exe:这是Windows操作系统中的可执行文件扩展名,包含可直接运行的程序代码。 # .msi:这是Microsoft Windows中的一种安装包文件格式,包含了安装所需的全部文件和信息。 # .rar:这是一种常见的压缩文件格式,使用这种格式可以将多个文件压缩成一个较小的文件以节省空间。 # .zip:这是另一种常见的压缩文件格式,与.rar类似,也可以将多个文件压缩成一个较小的文件。 # 常见的图片文件后缀(二进制格式) # * .jpg:这是最常用的照片文件格式,通常具有较高的图像质量。 # * .jpeg:这也是照片文件格式,通常比.jpg格式更小,但图像质量稍低。 # * .png:这是一种无损压缩的图像文件格式,通常用于创建透明背景的图像。 # * .gif:这是一种支持动画效果的图像文件格式,通常用于创建简单的动态图形。 # 常见的音频文件后缀(二进制格式) # * .bmp:这是一种位图图像文件格式,通常用于打印或处理高质量图像。 # * .tiff:这是一种标签图像文件格式,通常用于专业级别的图像处理和输出。 # * .mp4:这是一种常用的视频文件格式,广泛用于互联网上的视频分享和流媒体服务。 # * .mov:这是Apple公司开发的一种视频文件格式,通常用于其产品中的视频编辑和播放功能。 # * .avi:这是一种早期的视频文件格式,被广泛用于电影制作和电视节目录制等领域。
【3】文件的操作方法
# 读
f.read():读取所有内容,光标移动到最后
f.readline():读取一行内容,光标移动到第二行首部
f.readlines():读取每一行内容,并存放于列表中
with open('01.txt', 'r', encoding='utf8') as f1:
read1 = f1.read()
reset = f1.seek(0,0) # 光标回到开头
print(f1.tell()) # 0 光标位置
read2 = f1.readline()
read3 = f1.readline()
read4 = f1.readlines()
print(read1)
'''
第一行
第二行
第三行
共四行
'''
print(read2) # 第一行
print(read3) # 第二行
print(read4) # ['第三行\n', '共四行']
# 写
f.write()
f.writelines()
list1 = ['have', 'a', 'good', 'day']
with open('01.txt', 'w', encoding='utf8') as f1:
f1.write('Have a nice day!')
f1.writelines(list1)
# Have a nice day!haveagoodday
# 注意,如果没有特殊符号(\n等)区分,则会首尾接在一起
【4】判断文件状态
f.readable():是否可读
f.writable():是否可写
f.closed:是否已关闭
f.encoding:查看编码,如果文件打开模式为b,则没有该属性
f.flush():立刻将文件内容从内存刷到硬盘,相当于按了以下保存
f.name():获取文件的名字
【5】控制文件指针/光标的移动
(1)read(位移量)
- 文件内指针的移动都是Bytes为单位的,唯一例外的是t模式下的read(n),n以字符为单位
t
模式下,一个字符就是一个位移量b
模式下,单个英文字符或单个特殊符号是一个位移量,中文字符是三个位移量
# t 模式下 # 01.txt:Have 一个 nice day!
with open('01.txt', 'r', encoding='utf8') as f1:
# print(f1.read()) # Have 一个 nice day!
# print(f1.read(5)) # Have
print(f1.read(7)) # Have 一个
print(f1.read(5)) # nice # 未重置光标,继续从第7个字节移动
# 空格也算是一个位移量
(2)seek(位移量,模式)
- 之前文件内指针的移动都是由读/写操作而被动触发的,若想读取文件某一特定位置的数据,则则需要用f.seek方法主动控制文件内指针的移动,详细用法如下:
- f.seek(指针移动的字节数,模式控制):
- 模式控制:
- 0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的
- 1: 该模式代表指针移动的字节数是以当前所在的位置为参照的
- 2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的
- 强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用
# 0 模式 # 01.txt :Have 一个 nice day!
with open('01.txt', 'rt', encoding='utf8') as f1:
f1.seek(4, 0)
print(f1.tell()) # 4
print(f1.read()) # 一个 nice day! # 含空格
# 1 模式 # 01.txt :BCD嗨你好
with open('01.txt', 'rb') as f1:
f1.seek(3, 1) # 光标从默认开头位置向后移动3字节
print(f1.tell()) # 3
f1.seek(3, 1) # 6
print(f1.read()) # 解码前: b'\xe4\xbd\xa0\xe5\xa5\xbd'
print(f1.read().decode('utf8'))
# f1.read()已经将光标移至最后
# 不可在同一次打开文件中打开,此处为了方便理解
# 解码后:你好
- 补充:位移量
可正可负
,负数表示从后向前移动
练习
# 题目
张一蛋 山东 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422
将上段内容调整至
张一蛋(妇女主任) 山东 179 49 12344234523
李二蛋(村长) 河北 163 57 13913453521
王全蛋(书记) 山西 153 62 18651433422
with open('01.txt', 'r', encoding='utf-8') as file:
data = file.readlines()
line_list = []
for line in data:
if '张一蛋' in line:
line = line.replace(line.split()[0], f'{line.split()[0]}(妇女主任)')
elif '李二蛋' in line:
line = line.replace(line.split()[0], f'{line.split()[0]}(村长)')
elif '王全蛋' in line:
line = line.replace(line.split()[0], f'{line.split()[0]}(书记)')
line_list.append(line)
print(line_list)
with open('01.txt', 'w', encoding='utf-8') as fp:
fp.writelines(line_list)