news 2026/4/21 19:19:43

使用Python进行文件读写的API或方法及其注意事项

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用Python进行文件读写的API或方法及其注意事项

本文总结了Python文件读写的核心API及注意事项。


主要内容包括:

1)文件打开与关闭方法,推荐使用with语句自动管理资源;

2)文件读取方法,如read()、readline()等,注意大文件应使用迭代器方式;

3)文件写入方法及操作模式说明;

4)文件指针操作和常用辅助参数设置。


最佳实践建议:始终使用with语句,明确指定编码,根据场景选择合适方法(如大文件用迭代器)。


常见错误包括编码问题、文件指针位置错误等,可通过指定正确编码、seek(0)重置指针等方式解决。


使用Python进行文件读写的API或方法及其注意事项


以下是 Python 文件读写的核心 API 及注意事项总结表:


一、文件打开与关闭

API/方法功能说明示例注意事项
open(file, mode, encoding)打开文件,返回文件对象f = open('test.txt', 'r', encoding='utf-8')1. 必须指定正确的编码(如utf-8
2. 文件不存在时'r'模式会报错FileNotFoundError
3. 建议使用with语句自动管理资源
close()关闭文件对象f.close()1. 忘记关闭可能导致内存泄漏或数据丢失
2. 已关闭的文件无法再进行读写操作
3. 使用with语句可自动调用
with语句上下文管理器,自动关闭文件with open('test.txt', 'r') as f:推荐使用,即使发生异常也会自动关闭文件

二、文件读取方法

API/方法功能说明返回值注意事项
read(size=-1)读取指定字节数,默认读取全部字符串1. 大文件不建议无参读取,会耗尽内存
2. 读取后文件指针移动到末尾
3. 再次调用返回空字符串
readline(size=-1)读取一行字符串(包含换行符\n1. 文件末尾返回空字符串''
2. 换行符会被保留
3. 可用strip()去除换行符
readlines(hint=-1)读取所有行字符串列表(每行含\n1. 大文件同样有内存风险
2. 可用for line in f:逐行迭代更高效
迭代器方式逐行读取(内存友好)每行字符串for line in f:
process(line)

推荐大文件使用,不会一次性加载全部内容

三、文件写入方法

API/方法功能说明示例注意事项
write(str)写入字符串f.write('Hello\n')1. 不会自动添加换行符,需手动加\n
2. 返回写入的字符数
3. 需要配合flush()close()确保写入磁盘
writelines(lines)写入字符串列表f.writelines(['a\n', 'b\n'])1. 不会自动添加换行符
2. 需要自己保证每个元素末尾有\n
3. 适用于批量写入
flush()强制刷新缓冲区f.flush()立即将缓冲区数据写入磁盘,避免数据丢失

四、文件操作模式

模式说明文件指针位置文件不存在原有内容
'r'只读(默认)文件开头报错FileNotFoundError保留
'w'只写(覆盖)文件开头创建新文件清空
'a'追加文件末尾创建新文件保留
'x'独占创建文件开头创建新文件不存在(文件存在则报错)
'r+'读写文件开头报错保留(从头覆盖)
'w+'读写(覆盖)文件开头创建新文件清空
'a+'读追加文件末尾创建新文件保留
'b'二进制模式视主模式而定视主模式而定与文本模式配合使用,如'rb','wb'

五、文件指针操作

API/方法功能说明示例注意事项
tell()返回当前指针位置(字节数)pos = f.tell()1. 文本模式下可能不准确(多字节字符)
2. 二进制模式更可靠
seek(offset, whence)移动文件指针f.seek(0, 0)移到开头1.whence: 0=开头,1=当前位置,2=末尾
2. 文本模式只支持whence=0
3.offset需配合tell()返回值

六、常用辅助操作

API/方法功能说明示例注意事项
encoding参数指定文件编码encoding='utf-8'1. 必须指定,避免平台依赖
2. 常用编码:utf-8,gbk,gb2312
errors参数处理编码错误errors='ignore''replace'1.'ignore'忽略错误
2.'replace'?替换
3.'strict'抛出异常(默认)
newline参数控制换行符处理newline=''1. 读写 CSV 时建议设为''
2. 避免跨平台换行符问题

七、最佳实践总结

场景推荐方法示例代码
读小文件(<100MB)read()data = f.read()
读大文件迭代器for line in f: process(line)
读配置文件readlines()或迭代lines = f.readlines()
写少量数据write()f.write('data')
写大量数据writelines()f.writelines(lines)
需要随机访问seek()+tell()配合二进制模式使用
二进制文件(图片等)'rb'/'wb'f.read(1024)分块读取
自动资源管理with语句始终推荐

八、常见错误与解决方案

错误类型典型错误信息解决方案
编码错误'gbk' codec can't decode...指定正确的encoding参数
文件不存在FileNotFoundError检查路径或使用'w'/'a'模式
权限错误PermissionError关闭其他程序占用,检查文件只读属性
指针错误读到空数据检查是否在read()后忘了seek(0)
换行符问题写入内容挤在一行手动添加\n或使用print(file=f)

九、典型完整示例

python

# 推荐的标准写法 with open('file.txt', 'r', encoding='utf-8') as f: for line in f: # 逐行读取,内存友好 print(line.strip()) # 写入示例 with open('output.txt', 'w', encoding='utf-8') as f: f.write('第一行\n') f.writelines(['第二行\n', '第三行\n']) # 无需手动 close()

这个表格涵盖了 Python 文件操作的主要 API 和使用要点,建议在实际开发中优先使用with语句并明确指定编码。


补充:文件操作模式


以下是 Python 文件操作模式的完整补充,包括所有组合模式及详细说明:

一、基础模式完整版

模式读写权限文件指针位置文件不存在原有内容处理典型应用场景
'r'只读开头报错保留读取配置文件、日志分析
'w'只写开头创建清空生成新文件、覆盖旧数据
'a'只写末尾创建保留日志记录、追加数据
'x'只写开头创建(独占)不存在防止覆盖、创建锁文件
'r+'读写开头报错保留修改文件特定位置
'w+'读写开头创建清空需要读写的全新文件
'a+'读写末尾创建保留追加并读取(如日志分析)

二、二进制模式组合

模式说明数据类型换行符处理典型应用
'rb'二进制只读bytes无转换图片、视频、PDF、压缩包
'wb'二进制只写bytes无转换保存图片、序列化数据
'ab'二进制追加bytes无转换合并二进制文件
'xb'二进制独占创建bytes无转换避免覆盖二进制文件
'rb+'二进制读写bytes无转换修改二进制文件特定字节
'wb+'二进制读写(覆盖)bytes无转换创建可读写的二进制文件
'ab+'二进制读写(追加)bytes无转换追加并读取二进制数据

三、特殊模式组合

模式说明行为特点注意事项示例场景
'rt'文本只读(默认)'r'文本模式的标准写法明确指定文本模式
'wt'文本只写'w'明确指定文本模式生成文本文件
'at'文本追加'a'明确指定文本模式日志追加
'U'通用换行模式已弃用Python 3 中不再使用历史代码兼容

四、模式详细行为对比

4.1 文件指针位置详解

python

# 演示不同模式的指针位置 with open('test.txt', 'w') as f: f.write('1234567890') # r+ 模式:指针在开头 with open('test.txt', 'r+') as f: print(f.tell()) # 0 f.write('ABC') f.seek(0) print(f.read()) # ABC4567890 # a+ 模式:指针在末尾 with open('test.txt', 'a+') as f: print(f.tell()) # 10(文件末尾) f.write('XYZ') f.seek(0) print(f.read()) # ABC4567890XYZ

4.2 读写操作行为差异

模式执行read()执行write()执行seek()缓冲区行为
'r'✅ 可以❌ 报错✅ 可以行缓冲
'w'❌ 报错✅ 可以✅ 可以行缓冲
'a'❌ 报错✅ 可以(始终末尾)可移动但写操作回到末尾行缓冲
'r+'✅ 可以✅ 可以(覆盖)✅ 可以行缓冲
'w+'✅ 可以✅ 可以(清空后)✅ 可以行缓冲
'a+'✅ 可以(需先 seek)✅ 可以(始终末尾)读可移动,写强制末尾行缓冲

4.3 错误处理行为

python

# 不同模式对错误的处理 import os # 模式 'x' - 文件存在时报错 try: with open('existing.txt', 'x') as f: f.write('data') except FileExistsError: print("文件已存在,无法创建") # 模式 'r' - 文件不存在时报错 try: with open('not_exist.txt', 'r') as f: data = f.read() except FileNotFoundError: print("文件不存在") # 模式 'w' - 自动创建,不报错 with open('new_file.txt', 'w') as f: f.write('自动创建成功')

五、平台差异性说明

模式Linux/macOS 行为Windows 行为注意事项
文本模式换行符\n\r\n自动转换跨平台时注意编码
二进制模式无转换无转换推荐处理非文本文件
'a'模式写操作始终末尾写操作始终末尾Windows 某些情况有差异
文件锁定通常不锁定可能部分锁定Windows 更严格

六、实际应用场景示例

6.1 配置文件读写

python

# 使用 'r' 读取配置 def read_config(): with open('config.txt', 'r', encoding='utf-8') as f: return dict(line.strip().split('=') for line in f) # 使用 'w' 保存配置 def save_config(config): with open('config.txt', 'w', encoding='utf-8') as f: for key, value in config.items(): f.write(f"{key}={value}\n")

6.2 日志文件追加

python

import datetime def log_message(msg): # 'a' 模式自动追加,不会覆盖历史日志 with open('app.log', 'a', encoding='utf-8') as f: timestamp = datetime.datetime.now() f.write(f"[{timestamp}] {msg}\n")

6.3 二进制文件处理

python

# 复制图片(二进制模式) def copy_image(src, dst): with open(src, 'rb') as source: with open(dst, 'wb') as target: # 分块复制,避免内存爆炸 while chunk := source.read(8192): target.write(chunk) # 修改二进制文件特定位置 def patch_binary(filepath, offset, new_bytes): with open(filepath, 'r+b') as f: f.seek(offset) f.write(new_bytes)

6.4 临时文件安全创建

python

# 使用 'x' 模式避免覆盖 def safe_save(data, filename): try: with open(filename, 'x', encoding='utf-8') as f: f.write(data) print(f"成功创建 {filename}") except FileExistsError: print(f"文件 {filename} 已存在,拒绝覆盖") # 可以生成新文件名 base, ext = os.path.splitext(filename) new_name = f"{base}_new{ext}" return safe_save(data, new_name)

6.5 文件内容原地修改

python

# 使用 'r+' 模式修改文件特定行 def replace_line(filename, line_num, new_content): with open(filename, 'r+', encoding='utf-8') as f: lines = f.readlines() if 0 <= line_num < len(lines): lines[line_num] = new_content + '\n' f.seek(0) f.writelines(lines) f.truncate() # 截断多余内容

6.6 CSV 文件处理

python

import csv # 读取 CSV(文本模式) def read_csv(filename): with open(filename, 'r', newline='', encoding='utf-8') as f: return list(csv.reader(f)) # 写入 CSV(文本模式) def write_csv(filename, data): with open(filename, 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerows(data)

七、高级模式与标志位(底层 os.open)

os 标志说明Python 等效用途
os.O_RDONLY只读'r'底层文件操作
os.O_WRONLY只写'w'底层文件操作
os.O_RDWR读写'r+'底层文件操作
os.O_CREAT不存在则创建'w','a'自动创建
os.O_EXCLO_CREAT配合独占创建'x'原子性创建
os.O_TRUNC截断文件'w'清空内容
os.O_APPEND追加模式'a'原子性追加
os.O_SYNC同步写入无直接等效性能与可靠性平衡

八、性能对比与选择建议

场景推荐模式性能特点理由
大文件只读'r'利用系统缓存
频繁小写入'a'避免重复 seek
随机读写'r+b'需要多次 seek
日志追加'a'原子性操作
临时文件'x'避免冲突
二进制拷贝'rb','wb'无编码转换开销

九、常见陷阱与解决方案

陷阱表现解决方案
忘记二进制模式图片读写乱码使用'rb'/'wb'
'a+'读不到数据read()返回空seek(0)再读
'r+'意外覆盖写入位置不对精确使用seek()
'w'清空数据原有数据丢失改用'a'或备份
换行符混乱Windows 下\r\n问题二进制模式或指定newline

十、完整决策树

python

# 选择文件模式的决策逻辑 def choose_mode(read_needed, write_needed, append_mode, binary_mode, safe_create): if binary_mode: mode_base = 'b' else: mode_base = 't' # 可省略 if read_needed and write_needed: if safe_create: return 'w+' + mode_base # 安全创建但会清空 elif append_mode: return 'a+' + mode_base else: return 'r+' + mode_base elif read_needed: return 'r' + mode_base elif write_needed: if safe_create: return 'x' + mode_base elif append_mode: return 'a' + mode_base else: return 'w' + mode_base else: raise ValueError("至少需要读或写权限") # 使用示例 print(choose_mode(True, False, False, False, False)) # 'r' print(choose_mode(True, True, True, False, False)) # 'a+' print(choose_mode(False, True, False, True, False)) # 'wb' print(choose_mode(False, True, False, False, True)) # 'x'

这个补充涵盖了 Python 文件操作模式的所有细节,建议根据具体场景选择合适的模式组合。


错误示例:错误分析


#读文件 with open("C:\\Users\\86178\\Desktop\\aaa.txt",'r',encoding="utf-8") as f: con=f.read()#将文本的内容作为一个整体字符串,读出来 con1=f.readline() con2 = f.readlines()#把文本每行的内容 作为一个元素 放到列表里面 print(con) #输出 # aaa # bbb # ccc print(con1)#换行? print(con2)#[]? f.close()#关闭该线程 关闭文件

你的代码存在一个关键问题在调用了f.read()之后,文件指针已经移动到了文件末尾,因此后续的f.readline()f.readlines()无法再读取到任何内容。


问题分析

  1. f.read()读取整个文件,指针移到最后

  2. f.readline()从当前位置(文件末尾)读取,返回空字符串''

  3. f.readlines()同样从末尾读取,返回空列表[]

  4. 你看到的print(con1)输出空行,是因为打印了空字符串后自动换行

  5. f.close()其实可以省略(with语句会自动关闭)


修正后的代码

方案一:只使用一种读取方式

python

with open("C:\\Users\\86178\\Desktop\\aaa.txt", 'r', encoding="utf-8") as f: con = f.read() # 整体读取 print(con)

方案二:分别读取(需要重新打开或重置指针)

python

with open("C:\\Users\\86178\\Desktop\\aaa.txt", 'r', encoding="utf-8") as f: con = f.read() print("read()结果:") print(con) # 将指针移回文件开头 f.seek(0) con1 = f.readline() print("readline()结果:", repr(con1)) # 使用repr可以看到转义字符 con2 = f.readlines() print("readlines()结果:", con2)

方案三:分别打开文件

python

# 分别演示三种读取方式 with open("C:\\Users\\86178\\Desktop\\aaa.txt", 'r', encoding="utf-8") as f: print("1. read():") print(f.read()) with open("C:\\Users\\86178\\Desktop\\aaa.txt", 'r', encoding="utf-8") as f: print("\n2. readline():") print(repr(f.readline())) with open("C:\\Users\\86178\\Desktop\\aaa.txt", 'r', encoding="utf-8") as f: print("\n3. readlines():") print(f.readlines())

补充说明

  • readline():返回一行字符串(包含换行符\n),文件末尾返回空字符串''

  • readlines():返回所有行的列表,每行字符串包含换行符

  • repr()函数可以显示字符串的真实内容,包括\n等转义字符

  • seek(0):将文件指针移动到指定位置,0表示文件开头


类似错误


with open('day_07.py','w+',encoding="utf-8") as f: f.writelines("hello world\n")#覆盖写入 con = f.read() print(con)#为什么读不出数据? f.close()

问题在于文件指针位置!你的代码流程如下:


问题分析

python

with open('day_07.py', 'w+', encoding="utf-8") as f: f.writelines("hello world\n") # 1. 写入数据,指针在末尾(第13个字节后) con = f.read() # 2. 从末尾读取 → 读不到任何数据 print(con) # 3. 输出空字符串 f.close() # 4. with 语句会自动关闭,此行多余

关键点

  • writelines()写入后,文件指针停留在写入内容的末尾

  • 此时调用read(),从末尾开始读 → 返回空字符串


解决方案

方案一:先 seek(0) 再读取

python

with open('day_07.py', 'w+', encoding="utf-8") as f: f.writelines("hello world\n") f.seek(0) # 将指针移回文件开头 con = f.read() print(con) # 输出: hello world

方案二:先写入,关闭后重新读取

python

# 先写入 with open('day_07.py', 'w', encoding="utf-8") as f: f.writelines("hello world\n") # 再读取 with open('day_07.py', 'r', encoding="utf-8") as f: con = f.read() print(con) # 输出: hello world

方案三:使用 r+ 模式(需要文件已存在)

python

# 先创建文件 with open('day_07.py', 'w', encoding="utf-8") as f: f.writelines("hello world\n") # 再读写 with open('day_07.py', 'r+', encoding="utf-8") as f: con = f.read() print(con) # 输出: hello world f.write("\n追加内容") # 在末尾追加

各模式写入后的指针位置

模式写入操作写入后指针位置立即读取结果
'w+'write()/writelines()文件末尾空字符串(需seek(0)
'r+'write()写入位置末尾(可能覆盖)取决于写入位置
'a+'write()始终在文件末尾空字符串(需seek(0)
'w'write()文件末尾不支持读取

验证指针位置

python

# 演示指针位置变化 with open('day_07.py', 'w+', encoding="utf-8") as f: print(f"初始位置: {f.tell()}") # 0 f.writelines("hello world\n") print(f"写入后位置: {f.tell()}") # 13(假设12个字符+换行符) f.seek(0) print(f"seek(0)后位置: {f.tell()}") # 0 con = f.read() print(f"读取后位置: {f.tell()}") # 13(读完又到末尾) print(f"读取内容: {con}") # hello world

正确的 w+ 使用场景

w+模式适合以下场景:

场景1:写入后立即读取(需 seek)

python

with open('temp.txt', 'w+', encoding="utf-8") as f: # 生成数据 for i in range(10): f.write(f"第{i}行\n") # 需要读取时,先回到开头 f.seek(0) data = f.read() print(data)

场景2:清空文件后重新写入并验证

python

with open('config.txt', 'w+', encoding="utf-8") as f: f.write("new config data") f.seek(0) # 验证写入是否正确 if f.read() == "new config data": print("写入成功")

场景3:在内存中处理数据

python

# 使用 StringIO 更好,但 w+ 也可以 with open('data.txt', 'w+', encoding="utf-8") as f: # 先生成内容 lines = ["line1\n", "line2\n", "line3\n"] f.writelines(lines) # 处理这些数据 f.seek(0) processed = [line.upper() for line in f] print(processed) # ['LINE1\n', 'LINE2\n', 'LINE3\n']

其他注意事项

1. close() 是多余的

python

# with 语句会自动关闭文件,不需要手动 close() with open('day_07.py', 'w+', encoding="utf-8") as f: f.write("data") f.seek(0) print(f.read()) # 离开 with 块时自动关闭

2.writelines() 不会自动换行

python

# writelines() 不会自动添加换行符 with open('test.txt', 'w+') as f: f.writelines(["hello", "world"]) # 结果是 "helloworld" # 需要手动添加 with open('test.txt', 'w+') as f: f.writelines(["hello\n", "world\n"]) # 正确

3. 更清晰的替代方案

python

# 如果只是创建新文件并写入,用 'w' 模式 with open('day_07.py', 'w', encoding="utf-8") as f: f.writelines("hello world\n") # 单独读取 with open('day_07.py', 'r', encoding="utf-8") as f: print(f.read())

总结

你的代码读不出数据的原因writelines()后指针在文件末尾,read()从末尾开始读导致返回空字符串。

解决方法:在读取前添加f.seek(0)将指针移回开头。

最佳实践:除非确实需要读写切换,否则建议使用单一目的的模式'r'只读或'w'只写),代码意图更清晰。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 19:18:39

如何格式化SQL日期显示_掌握DATE_FORMAT函数的高级用法

DATE_FORMAT 返回 NULL 主因是首参非合法日期&#xff0c;如空字符串、0000-00-00 或非法格式&#xff08;如 2024-13-01&#xff09;&#xff1b;MySQL 严格模式拒解析&#xff0c;非严格模式转为 0 导致结果为 NULL。DATE_FORMAT 为什么返回 NULL 而不是你想要的日期字符串常…

作者头像 李华
网站建设 2026/4/21 19:17:22

ROS导航实战:从地图构建到自主避障的完整流程解析

1. ROS导航系统概述 第一次接触ROS导航功能时&#xff0c;我被它强大的模块化设计深深震撼。想象一下&#xff0c;你组装了一台扫地机器人&#xff0c;只需要配置好激光雷达和底盘驱动&#xff0c;就能让它自动规划路线清扫房间——这就是ROS导航堆栈(navigation stack)带来的可…

作者头像 李华
网站建设 2026/4/21 19:16:13

终极视频号批量下载指南:从3小时到3分钟的完整解决方案

终极视频号批量下载指南&#xff1a;从3小时到3分钟的完整解决方案 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 在数字内容…

作者头像 李华
网站建设 2026/4/21 19:15:07

别再乱接线了!详解家用路由器误接导致企业网络瘫痪的环路检测实战

家用路由器误接引发的企业网络风暴&#xff1a;环路检测实战指南 上周五下午3点&#xff0c;某科技公司突然全员断网——市场部无法访问CRM系统&#xff0c;研发团队Git提交全部失败&#xff0c;连会议室投屏都成了奢望。IT部门紧急排查后发现&#xff0c;罪魁祸首竟是前台新接…

作者头像 李华
网站建设 2026/4/21 19:15:03

网页图片格式转换难?Chrome右键一键解决图片格式不兼容问题

网页图片格式转换难&#xff1f;Chrome右键一键解决图片格式不兼容问题 【免费下载链接】Save-Image-as-Type Save Image as Type is an chrome extension which add Save as PNG / JPG / WebP to the context menu of image. 项目地址: https://gitcode.com/gh_mirrors/sa/S…

作者头像 李华