文件读写和异常处理
文件读写和异常处理:原理、用法与最佳实践教学指南
一、文件系统与数据持久化
概念回顾:
- 持久化(Persistence):将数据从内存转存到磁盘,常用方式为“写入文件”。
- 文件系统(File System):负责数据的存储、检索与组织,是操作系统的一部分,为用户隐藏硬盘数据块的细节,提供“文件 + 目录”的操作接口。
教学要点:
- 使用文件可实现数据持久化,适合保存日志、配置、缓存、静态资源等。
- 文件系统管理磁盘空间,无需手动分配存储块,程序员只需指定路径与文件名。
二、打开和关闭文件
基础语法:
open(file, mode='r', encoding=None)
常见模式总结:
模式 | 说明 |
---|---|
'r' |
只读,文件不存在则异常 |
'w' |
写入,文件存在则清空 |
'x' |
写入,若文件已存在则异常 |
'a' |
追加写入 |
'b' |
二进制模式 |
't' |
文本模式(默认) |
'+' |
更新模式,读写均可 |
实践建议:
- 指定
encoding='utf-8'
避免跨平台字符集问题。 - 文件操作后一定要关闭文件,以释放资源。
教学案例:
f = open('example.txt', 'w', encoding='utf-8')
f.write('Hello, Python!')
f.close()
三、读写文本文件
读取方法:
read()
:读取所有内容。readline()
:读取一行。readlines()
:按行读成列表。for line in file:
:逐行读取。
写入方法:
write(str)
:写入字符串。- 使用
'w'
或'a'
模式。
教学示例:
with open('note.txt', 'r', encoding='utf-8') as f:
for line in f:
print(line.strip())
最佳实践:
- 写入前尽量先判断文件是否存在(如使用
os.path.exists
)。 - 使用
strip()
去除换行符。
四、异常处理机制(Exception Handling)
关键词讲解:
关键词 | 说明 |
---|---|
try |
尝试执行可能出错的代码块 |
except |
出现异常时执行的代码 |
else |
无异常时执行的代码 |
finally |
无论是否异常都执行的代码(常用于释放资源) |
raise |
主动抛出异常 |
教学范例:
try:
f = open('not_exist.txt', 'r')
except FileNotFoundError:
print("文件不存在!")
finally:
print("程序结束")
最佳实践:
- 不要滥用
except
捕获所有异常(如:except:
),会掩盖Bug。 - 仅处理你能处理的异常,如:
except FileNotFoundError
。 - 在
finally
中释放文件、网络、数据库等资源。 - 尽量使用
with
语法自动处理资源释放。
五、自定义异常与抛出
定义自定义异常:
class MyError(Exception):
pass
抛出异常:
def check(n):
if n < 0:
raise MyError("不能为负数")
教学场景:
- 参数非法时引发异常。
- 模块之间传递错误状态。
六、上下文管理器(with语法)
优点:
- 自动关闭文件,简化代码。
- 防止忘记调用
close()
导致资源泄露。
语法示例:
with open('data.txt', 'r', encoding='utf-8') as f:
data = f.read()
教学建议:
- 几乎所有文件操作推荐使用
with
。 - 支持
with open(...) as f1, open(...) as f2:
的多文件写法。
七、读写二进制文件
区别于文本文件:
- 模式为
'rb'
/'wb'
。 - 操作的是
bytes
而非str
。 - 常用于图片、视频、音频、PDF等非文本数据。
简单复制图片示例:
with open('a.jpg', 'rb') as src, open('b.jpg', 'wb') as dst:
dst.write(src.read())
分块读写(适合大文件):
with open('bigfile.dat', 'rb') as f1, open('copy.dat', 'wb') as f2:
chunk = f1.read(1024)
while chunk:
f2.write(chunk)
chunk = f1.read(1024)
教学点:
- 分块操作可节省内存。
- 注意避免读取时漏加参数,默认
read()
可能读取整个文件。
八、综合示例:文件操作 + 异常处理 + 上下文语法
def safe_read(path):
try:
with open(path, 'r', encoding='utf-8') as file:
return file.read()
except FileNotFoundError:
return '文件未找到'
except UnicodeDecodeError:
return '编码错误'
except Exception as e:
return f'发生未知错误:{e}'
教学扩展:
- 可以引入日志记录模块(如
logging
)记录异常。 - 可以使用函数封装读取逻辑,提高重用性。
九、教学总结与最佳实践
✅ 推荐做法:
- 用
with open(...)
替代open
+close
。 - 捕获特定异常类型,避免泛用
except:
- 分离异常处理逻辑与主业务逻辑。
- 使用文本文件存储结构化数据(如JSON、CSV)时,建议使用标准库支持。
- 对于大文件使用分块读写方式,避免内存压力。
- 自定义异常用于标志业务规则违反,而非系统错误。
🚫 避免误区:
- 不要使用异常控制正常流程(如用
try
处理文件是否存在)。 - 不要捕获所有异常再重新抛出同一个异常。
- 文件读写中不要忽略字符编码的重要性。
如需扩展学习内容(如使用 json
模块进行持久化、临时文件操作、文件权限控制等),可随时继续提问。