Python星球日记 - 第11天:文件操作
🌟引言:
上一篇:Python星球日记:第10天 - 模块与包
名人说:不要人夸颜色好,只留清气满乾坤(王冕《墨梅》)
创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)
目录
- 一、文件操作基础
- 1. 文件的打开与关闭
- 2. 文件读写模式
- 3. 文件读写方法
- 1️⃣读取文件内容
- 2️⃣写入文件内容
- 二、异常处理
- 三、综合案例:统计文本文件中的行数和单词数
- 四、文件操作的最佳实践
- 五、练习题(附参考解答)
- 练习一:创建简单的日志记录器
- 练习二:文件内容查找和替换
- 练习三:CSV文件数据分析
- 六、总结
专栏介绍: Python星球日记专栏介绍(持续更新ing)
更多Python知识,请关注我、订阅专栏《 Python星球日记》,内容持续更新中…
欢迎来到Python星球🪐的第11天!
在编程世界中,文件操作是一项基础但极其重要的技能。
通过文件操作,我们可以将数据永久保存,或者从外部文件读取信息,这极大地扩展了程序的功能和应用范围。今天,我们将探索Python中的文件操作,学习如何打开、读取、写入和关闭文件,以及如何优雅地处理可能出现的异常情况。
一、文件操作基础
1. 文件的打开与关闭
在Python中,处理文件的第一步是使用open()
函数打开它。无论是读取还是写入,我们都需要先建立与文件的连接。
# 打开文件的基本语法
file = open('filename.txt', 'mode')
这里的filename.txt
是文件名,mode
是打开模式(如’r’表示读取)。
重要提示:打开文件后,一定要记得关闭它!这不仅是良好的编程习惯,也能防止资源泄露。
# 关闭文件
file.close()
更优雅的方式是使用with
语句,它会在代码块结束时自动关闭文件:
# 使用with语句(推荐方式)
with open('filename.txt', 'r') as file:
# 进行文件操作
content = file.read()
# 离开with块后,文件会自动关闭
2. 文件读写模式
Python提供了多种文件操作模式,用于控制我们如何与文件交互:
模式 | 描述 |
---|---|
'r' | 读取模式(默认)- 只能读取文件,不能写入 |
'w' | 写入模式 - 创建新文件写入(如果文件已存在则覆盖) |
'a' | 追加模式 - 在文件末尾添加内容,不覆盖原有内容 |
'r+' | 读写模式 - 可以读取也可以写入 |
'b' | 二进制模式 - 可与其他模式组合,如’rb’或’wb’ |
例如,要以写入模式打开文件new_file.txt
:
with open('new_file.txt', 'w') as file:
file.write('Hello, Python!')
①运行前
new_file.txt
中没有任何内容
②运行后
可以看到,new_file.txt
中已经写入了我们要写入的文本内容。
3. 文件读写方法
1️⃣读取文件内容
Python提供了多种方法来读取文件内容:
# 读取整个文件内容为一个字符串
with open('example.txt', 'r') as file:
content = file.read()
print(content)
# 读取单行
with open('example.txt', 'r') as file:
line = file.readline()
print(line)
# 读取所有行到一个列表中
with open('example.txt', 'r') as file:
lines = file.readlines()
for line in lines:
print(line, end='') # readlines()保留了换行符,所以这里不再添加
# 通过迭代器逐行读取(内存效率高)
with open('example.txt', 'r') as file:
for line in file:
print(line, end='')
2️⃣写入文件内容
写入文件同样简单:
# 写入字符串
with open('output.txt', 'w') as file:
file.write('这是第一行\n')
file.write('这是第二行\n')
# 写入多行
lines = ['第一行\n', '第二行\n', '第三行\n']
with open('output.txt', 'w') as file:
file.writelines(lines)
二、异常处理
在文件操作中,可能会遇到各种异常情况,如文件不存在、权限问题等。使用try...except
语句可以优雅地处理这些异常:
try:
with open('non_existent_file.txt', 'r') as file:
content = file.read()
except FileNotFoundError:
print("文件不存在!")
except PermissionError:
print("没有权限读取该文件!")
except Exception as e:
print(f"发生了其他错误: {e}")
常见的文件操作异常包括:
- FileNotFoundError:文件不存在
- PermissionError:没有足够权限
- IOError:输入/输出操作失败
- IsADirectoryError:试图对目录执行文件操作
异常处理流程:
:
三、综合案例:统计文本文件中的行数和单词数
下面是一个完整的程序,用于统计文本文件中的行数和单词数:
def count_lines_and_words(filename):
"""统计文件的行数和单词数"""
try:
with open(filename, 'r', encoding='utf-8') as file:
# 读取所有行
lines = file.readlines()
# 统计行数
line_count = len(lines)
# 统计单词数
word_count = 0
for line in lines:
# 移除前后空白,然后按空格分割单词
words = line.strip().split()
word_count += len(words)
return line_count, word_count
except FileNotFoundError:
print(f"错误:文件 '{filename}' 不存在!")
return 0, 0
except Exception as e:
print(f"处理文件时发生错误: {e}")
return 0, 0
# 主程序
if __name__ == "__main__":
file_name = input("请输入要统计的文件名:")
lines, words = count_lines_and_words(file_name)
if lines > 0 or words > 0:
print(f"\n文件统计结果:")
print(f"- 行数: {lines}")
print(f"- 单词数: {words}")
这个程序展示了如何:
- 打开并读取文件
- 处理文件内容(计算行数和单词数)
- 优雅地处理可能出现的异常
四、文件操作的最佳实践
- 始终使用
with
语句:自动处理文件关闭,即使发生异常也能确保资源释放 - 指定字符编码:处理非ASCII文本时,明确指定编码(如
encoding='utf-8'
) - 适当的异常处理:针对可能出现的异常进行处理,提高程序稳健性
- 大文件处理:对于大文件,避免一次性读取全部内容,而是使用迭代器逐行处理
- 适当的模式选择:根据实际需求选择合适的文件操作模式,避免数据意外丢失
五、练习题(附参考解答)
下面是三个关于Python文件操作的练习题,每个练习题都包含参考解答,帮助你巩固所学的文件操作知识。
练习一:创建简单的日志记录器
题目:创建一个简单的日志记录函数log_message()
,能够将日志信息追加到日志文件中。日志应包含时间戳、日志级别(INFO, WARNING, ERROR)和消息内容。
参考解答:
import datetime
def log_message(message, level="INFO", log_file="app.log"):
"""
将带有时间戳和日志级别的消息追加到日志文件
参数:
message (str): 要记录的消息
level (str): 日志级别 ("INFO", "WARNING", "ERROR")
log_file (str): 日志文件名
"""
# 获取当前时间
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 格式化日志条目
log_entry = f"[{timestamp}] [{level}] {message}\n"
# 以追加模式打开文件并写入日志
try:
with open(log_file, 'a') as file:
file.write(log_entry)
print(f"日志已记录到 {log_file}")
except Exception as e:
print(f"记录日志时发生错误: {e}")
# 测试函数
if __name__ == "__main__":
log_message("应用启动")
log_message("用户尝试未经授权的操作", "WARNING")
log_message("数据库连接失败", "ERROR")
练习二:文件内容查找和替换
题目:编写一个函数find_and_replace()
,接受文件名、要查找的字符串和替换字符串作为参数,将文件中所有匹配的字符串替换为新字符串,并保存为新文件(原文件名基础上加上"_modified"后缀)。
参考解答:
def find_and_replace(filename, find_str, replace_str):
"""
在文件中查找并替换所有匹配的字符串,结果保存到新文件
参数:
filename (str): 要处理的文件名
find_str (str): 要查找的字符串
replace_str (str): 替换用的字符串
返回:
bool: 操作是否成功
"""
# 生成新文件名
name_parts = filename.split('.')
if len(name_parts) > 1:
# 处理有扩展名的情况
new_filename = f"{name_parts[0]}_modified.{name_parts[1]}"
else:
# 处理没有扩展名的情况
new_filename = f"{filename}_modified"
try:
# 读取原文件内容
with open(filename, 'r', encoding='utf-8') as file:
content = file.read()
# 执行替换
modified_content = content.replace(find_str, replace_str)
# 记录替换次数
replace_count = content.count(find_str)
# 写入新文件
with open(new_filename, 'w', encoding='utf-8') as file:
file.write(modified_content)
print(f"替换完成! 共替换了 {replace_count} 处匹配项")
print(f"修改后的内容已保存到: {new_filename}")
return True
except FileNotFoundError:
print(f"错误: 文件 '{filename}' 不存在!")
return False
except Exception as e:
print(f"处理文件时发生错误: {e}")
return False
# 测试函数
if __name__ == "__main__":
test_filename = "test.txt"
# 创建测试文件
with open(test_filename, 'w') as f:
f.write("Python是一种强大的编程语言。\nPython非常易于学习。\n每个人都应该学习Python。")
# 测试替换函数
find_and_replace(test_filename, "Python", "Python3")
练习三:CSV文件数据分析
题目:编写一个程序,读取包含学生成绩的CSV文件(格式:姓名,数学,英语,科学),计算每个学生的平均分和总分,以及每门课程的平均分,并将结果写入新的CSV文件。
参考解答:
def analyze_grades(input_file, output_file):
"""
分析CSV格式的学生成绩数据
参数:
input_file (str): 输入CSV文件名
output_file (str): 输出CSV文件名
"""
try:
# 读取CSV文件
with open(input_file, 'r', encoding='utf-8') as file:
# 读取第一行(标题行)
header = file.readline().strip().split(',')
# 初始化数据结构
students = []
subject_totals = [0] * (len(header) - 1) # 减1是因为第一列是姓名
subject_counts = [0] * (len(header) - 1)
# 读取学生数据
for line in file:
data = line.strip().split(',')
name = data[0]
# 转换成绩为数字
grades = []
for i in range(1, len(data)):
try:
grade = float(data[i])
grades.append(grade)
# 更新科目总分和计数
subject_totals[i-1] += grade
subject_counts[i-1] += 1
except ValueError:
# 处理无效成绩
grades.append(0)
print(f"警告: '{name}'的'{header[i]}'成绩无效,已设为0")
# 计算学生总分和平均分
total = sum(grades)
average = total / len(grades) if grades else 0
# 保存学生数据
students.append({
'name': name,
'grades': grades,
'total': total,
'average': average
})
# 计算每门课程的平均分
subject_averages = [total / count if count > 0 else 0
for total, count in zip(subject_totals, subject_counts)]
# 写入结果到新CSV文件
with open(output_file, 'w', encoding='utf-8') as file:
# 写入标题行
file.write("姓名,")
file.write(",".join(header[1:]))
file.write(",总分,平均分\n")
# 写入每个学生的数据
for student in students:
file.write(f"{student['name']},")
file.write(",".join(str(grade) for grade in student['grades']))
file.write(f",{student['total']:.2f},{student['average']:.2f}\n")
# 写入每门课程的平均分
file.write("课程平均分,")
file.write(",".join(f"{avg:.2f}" for avg in subject_averages))
file.write("\n")
print(f"分析完成,结果已保存到 {output_file}")
except FileNotFoundError:
print(f"错误: 文件 '{input_file}' 不存在!")
except Exception as e:
print(f"处理文件时发生错误: {e}")
# 测试函数
if __name__ == "__main__":
# 创建测试数据
with open("grades.csv", 'w', encoding='utf-8') as f:
f.write("姓名,数学,英语,科学\n")
f.write("张三,95,82,78\n")
f.write("李四,88,90,85\n")
f.write("王五,76,85,92\n")
f.write("赵六,92,78,85\n")
# 分析成绩
analyze_grades("grades.csv", "grades_analysis.csv")
这些练习题从简单到复杂,涵盖了文件读写、异常处理、数据处理等方面,能够帮助你全面掌握Python文件操作的技能。解答中附带了详细的注释,让你更容易理解代码的执行流程和关键步骤。
六、总结
通过本篇文章,我们学习了Python中的基本文件操作技能:
- 如何使用
open()
和close()
打开和关闭文件 - 不同的文件读写模式(
r
、w
、a
等)的用途 - 各种文件读写方法(
read()
、write()
、readlines()
等) - 使用
try...except
处理文件操作异常 - 通过实际案例掌握文件操作技巧
文件操作是Python编程中的基础技能,掌握它将为您的数据处理、配置管理、日志记录等任务提供有力工具。无论是处理小型文本文件还是大型数据集,这些知识都将派上用场。
如果你喜欢这篇文章,请点赞、收藏并关注我的专栏Python星球日记!每天都会有新的Python学习内容等着你!
创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)
如果你对今天的内容有任何问题,或者想分享你的学习心得,欢迎在评论区留言讨论!