当前位置: 首页 > news >正文

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}")

这个程序展示了如何:

  1. 打开并读取文件
  2. 处理文件内容(计算行数和单词数)
  3. 优雅地处理可能出现的异常

四、文件操作的最佳实践

  1. 始终使用with语句:自动处理文件关闭,即使发生异常也能确保资源释放
  2. 指定字符编码:处理非ASCII文本时,明确指定编码(如encoding='utf-8'
  3. 适当的异常处理:针对可能出现的异常进行处理,提高程序稳健性
  4. 大文件处理:对于大文件,避免一次性读取全部内容,而是使用迭代器逐行处理
  5. 适当的模式选择:根据实际需求选择合适的文件操作模式,避免数据意外丢失

五、练习题(附参考解答)

下面是三个关于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()打开和关闭文件
  • 不同的文件读写模式(rwa等)的用途
  • 各种文件读写方法(read()write()readlines()等)
  • 使用try...except处理文件操作异常
  • 通过实际案例掌握文件操作技巧

文件操作是Python编程中的基础技能,掌握它将为您的数据处理、配置管理、日志记录等任务提供有力工具。无论是处理小型文本文件还是大型数据集,这些知识都将派上用场。


如果你喜欢这篇文章,请点赞、收藏并关注我的专栏Python星球日记!每天都会有新的Python学习内容等着你!

创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)
如果你对今天的内容有任何问题,或者想分享你的学习心得,欢迎在评论区留言讨论!

相关文章:

  • 【项目日记】高并发服务器项目总结
  • [环境配置] 1. 开发环境搭建
  • 自制简易 Shell:像搭建积木小屋一样打造命令交互小天地
  • (一)栈结构、队列结构
  • Quartz SpringBoot整合定时任务的基础使用方法 任务调度 定时器 单机版
  • [Android] 奇酷阅读V1.0.0 集小说、漫画、听书三合一 内置600多条源
  • MySQL 约束(入门版)
  • javaweb自用笔记:配置优先级、Bean管理、springBoot原理
  • Android SELinux权限使用
  • 数字音频基础​​
  • Vue3:初识Vue,Vite服务器别名及其代理配置
  • HCIP实验
  • linux 使用 usermod 授权 普通用户 属组权限
  • 农业股龙头公司有哪些?
  • windows10安装配置并使用Miniconda3
  • Python爬虫第6节-requests库的基本用法
  • 线性方程组的解法
  • C语言递归
  • 输入的格式问题
  • linux命令之yes(Linux Command Yes)
  • 做爰视频在线观看免费网站/网络营销的应用研究论文
  • 网站建设参考网站的说明书/做推广app赚钱的项目
  • 香港主机做电影网站/收录优美的图片app
  • 中山高端网站建设公司/电脑培训机构
  • 做外贸网站应该关注哪些地方/百度网址大全下载
  • 什么网站可以做直播/建网站找谁