第 10 章 文件和异常
文章目录
- 1.第 10 章 文件和异常
- 10.1 读取文件
- 10.1.1 读取文件的全部内容
- 10.1.2 相对文件路径和绝对文件路径
- 10.1.3 访问文件中的各行
- 10.1.4 使用文件的内容
- 10.1.5 包含100万位的大型文件
- 10.1.6 圆周率值中包含你的生日吗
- 10.2 写入文件
- 10.2.1 写入一行
- 10.2.2 写入多行
- 10.3 异常
- 10.3.1 处理ZeroDivisionError异常
- 10.3.2 使用try-except代码块
- 10.3.3 使用异常避免崩溃
- 10.3.4 else代码块
- 10.3.5 处理FileNotFoundError异常
- 10.3.6 分析文本
- 10.3.7 使用多个文件
- 10.3.8 静默失败
- 10.3.9 决定报告哪些错误
- 10.4 存储数据
- 10.4.1 使用json.dumps()和json.loads()
- 10.4.2 保存和读取用户生成的数据
- 10.4.3 重构
- 10.5 小结
- 总结
提示:
1.第 10 章 文件和异常
10.1 读取文件
文件读取是程序与外部数据交互的基础,核心在于通过文件路径找到目标文件,并按需求提取内容。
10.1.1 读取文件的全部内容
- 操作方式:使用
open()
函数打开文件(需指定文件路径),通过read()
方法读取全部内容,最后用close()
关闭文件(避免资源占用)。 - 示例代码:
with open('file.txt') as file_object: # with语句自动关闭文件,更安全contents = file_object.read()print(contents)
- 说明:
read()
会将文件内容作为字符串返回,末尾可能包含空行(因文件结束符导致),可通过strip()
去除。
10.1.2 相对文件路径和绝对文件路径
- 相对路径:相对于当前运行程序所在目录的路径。例如,程序在
project
文件夹,文件在project/data
中,则路径为'data/file.txt'
。 - 绝对路径:从根目录开始的完整路径(如Windows的
'C:/project/data/file.txt'
,Linux的'/home/user/project/file.txt'
)。 - 选择原则:程序与文件在同一项目内时用相对路径(更灵活);文件位置固定且与程序分离时用绝对路径。
10.1.3 访问文件中的各行
- 需求:逐行读取文件(适用于处理大型文件或按行分析数据)。
- 实现方式:通过
for
循环遍历文件对象:with open('file.txt') as file_object:for line in file_object:print(line.rstrip()) # rstrip()去除每行末尾的换行符
10.1.4 使用文件的内容
- 场景:读取内容后进行处理(如计算、分析、格式化输出等)。
- 示例:统计文件中包含特定单词的行数,或提取数值进行计算。
10.1.5 包含100万位的大型文件
- 处理逻辑:大型文件不宜一次性读取(可能占用过多内存),应逐行或分块读取。
- 优势:
with
语句和逐行遍历天然支持大型文件,无需担心内存溢出。
10.1.6 圆周率值中包含你的生日吗
- 应用案例:读取包含100万位圆周率的文件,检查其中是否包含指定的生日数字(如
'19901001'
)。 - 核心操作:用
read()
读取全部内容后,通过in
关键字判断字符串是否包含目标子串。
10.2 写入文件
程序可将数据持久化到文件中,方便后续使用或共享。
10.2.1 写入一行
- 打开模式:
open()
函数需指定'w'
(写入模式,会覆盖原有内容)、'a'
(追加模式,在末尾添加内容)等。 - 示例:
with open('output.txt', 'w') as file_object: # 'w'模式:若文件不存在则创建,存在则覆盖file_object.write("Hello, World!")
- 注意:
write()
不会自动添加换行符,需手动加入'\n'
。
10.2.2 写入多行
- 方式1:在字符串中加入
'\n'
换行符:with open('output.txt', 'a') as file_object: # 'a'模式:追加内容file_object.write("First line.\n")file_object.write("Second line.\n")
- 方式2:使用
writelines()
传入字符串列表(需自行处理换行)。
10.3 异常
异常是程序运行时的错误(如除以0、文件不存在),通过异常处理可避免程序崩溃,增强鲁棒性。
10.3.1 处理ZeroDivisionError异常
- 异常场景:除数为0时触发,例如
5 / 0
。 - 作用:直接运行会导致程序崩溃,需捕获并处理。
10.3.2 使用try-except代码块
- 语法:
try
块包含可能出错的代码,except
块处理特定异常。try:print(5 / 0) except ZeroDivisionError:print("不能除以0!")
10.3.3 使用异常避免崩溃
- 核心思想:即使出现异常,程序也能继续执行后续代码,而非直接终止。
- 示例:用户输入除数时,若输入0,通过异常处理提示错误并重新输入。
10.3.4 else代码块
- 作用:当
try
块无异常时执行,用于存放正常逻辑代码,使结构更清晰。try:x = int(input("请输入被除数:"))y = int(input("请输入除数:"))result = x / y except ZeroDivisionError:print("除数不能为0!") else:print(f"结果是:{result}") # 无异常时执行
10.3.5 处理FileNotFoundError异常
- 异常场景:打开不存在的文件时触发。
- 处理方式:捕获异常并提示用户文件不存在。
try:with open('missing_file.txt') as f:contents = f.read() except FileNotFoundError:print("找不到指定的文件!")
10.3.6 分析文本
- 案例:读取文本文件,统计单词数量(结合异常处理,避免文件不存在导致程序崩溃)。
- 实现:用
split()
将文本拆分为单词列表,再用len()
统计。
10.3.7 使用多个文件
- 逻辑:通过循环处理多个文件,统一应用读取和分析逻辑,配合异常处理确保某一文件出错时不影响其他文件。
10.3.8 静默失败
- 场景:不希望显示异常信息,仅忽略错误(使用
pass
语句)。try:with open('file.txt') as f:contents = f.read() except FileNotFoundError:pass # 静默处理,不做任何操作
10.3.9 决定报告哪些错误
- 原则:对用户操作错误(如文件不存在)应提示;对程序内部错误(如逻辑漏洞)应暴露,便于调试。
10.4 存储数据
使用json
模块可将Python数据(如字典、列表)存储为文件,方便后续读取和复用。
10.4.1 使用json.dumps()和json.loads()
- json.dumps():将Python对象转换为JSON字符串(序列化)。
- json.loads():将JSON字符串转换为Python对象(反序列化)。
- 示例:
import json# 序列化 data = {'name': 'Alice', 'age': 30} json_str = json.dumps(data) print(json_str) # 输出:{"name": "Alice", "age": 30}# 反序列化 python_data = json.loads(json_str) print(python_data['name']) # 输出:Alice
10.4.2 保存和读取用户生成的数据
- 保存:用
json.dump()
直接将数据写入文件。with open('user_data.json', 'w') as f:json.dump(data, f) # 将data写入文件
- 读取:用
json.load()
从文件中加载数据。with open('user_data.json') as f:loaded_data = json.load(f) # 从文件读取数据
10.4.3 重构
- 定义:优化代码结构(如拆分复杂函数为多个简洁函数),不改变功能但提高可读性和可维护性。
- 示例:将“读取JSON数据”“处理数据”“保存数据”拆分为独立函数。
10.5 小结
- 文件操作:掌握
open()
、read()
、write()
等方法,以及相对/绝对路径的使用,能读写文本文件。 - 异常处理:通过
try-except-else
捕获和处理错误(如ZeroDivisionError
、FileNotFoundError
),避免程序崩溃。 - 数据存储:用
json
模块序列化和反序列化数据,实现Python对象与文件的持久化交互。
通过本章学习,你可以实现程序与外部文件的灵活交互,同时增强程序的稳定性和实用性。