本章摘要

  1. 核心目标:掌握文件读取与写入,让程序的数据能保存到磁盘并重新加载
  2. 核心知识点:open() 函数、r/w/a 三种模式、read/readline/readlineswrite/writelineswith 上下文管理器、文件路径
  3. 实操产出:日记本程序,支持写入日记、读取历史记录
  4. 前置基础:第9-11章函数基础与进阶、第8章字符串操作、第3章异常处理概念

一、写在前面

前面写的程序有一个共同的问题:程序一关,数据全没了。变量、字典、列表里的数据都存在内存中,程序结束就消失。

想让数据"活下来",就需要把它写到文件里。文件存在硬盘上,关机也不会丢。这一章学习 Python 怎么读写文件——从最基础的 open() 到推荐的 with 写法,一步步来。


二、打开文件:open()

open() 是 Python 内置函数,用来打开文件,返回一个文件对象:

f = open("test.txt", "r")    # 以只读模式打开
content = f.read()            # 读取内容
print(content)
f.close()                     # 关闭文件(重要!)

2.1 文件打开模式

模式含义文件不存在时特点
"r"只读(默认)报错只能读取,不能修改
"w"只写自动创建覆盖原有内容
"a"追加自动创建在末尾添加,不覆盖
"r+"读写报错可读可写

在这里插入图片描述

最重要的区别"w" 会清空原文件再写入,"a" 不会。新手用 "w" 时要特别小心,别把重要文件覆盖了。


三、读取文件

3.1 read():一次读完

f = open("test.txt", "r")
content = f.read()    # 一次性读取全部内容
print(content)
f.close()

文件很大时不要用 read(),会占用大量内存。

3.2 readline():一次读一行

f = open("test.txt", "r")
line1 = f.readline()    # 读第一行
line2 = f.readline()    # 读第二行
print(line1, end="")    # readline 末尾自带换行符,print 的 end="" 避免多空一行
print(line2, end="")
f.close()

3.3 readlines():读所有行存列表

f = open("test.txt", "r")
lines = f.readlines()    # 每一行作为列表的一个元素
print(lines)             # ['第一行\n', '第二行\n', '第三行']
f.close()

3.4 最推荐:for 循环逐行读取

f = open("test.txt", "r")
for line in f:           # 直接遍历文件对象,一行一行读
    print(line, end="")  # 内存友好,适合大文件
f.close()

四种读取方式的区别:read() 一次全读、readline() 一次一行、readlines() 全读存列表、for line in f 逐行遍历。日常用 for 最多。


四、写入文件

4.1 write() 写入字符串

f = open("diary.txt", "w")    # "w" 模式:覆盖写入
f.write("2026年7月8日\n")
f.write("今天学习了文件读写。\n")
f.close()

4.2 writelines() 写入多行

lines = ["第一行\n", "第二行\n", "第三行\n"]
f = open("notes.txt", "w")
f.writelines(lines)    # 注意:writelines 不会自动加换行符
f.close()

4.3 追加写入

f = open("diary.txt", "a")    # "a" 模式:追加写入
f.write("追加一段新内容。\n")
f.close()

write()writelines()不会自动加换行符,需要手动在字符串末尾加 \n


五、with 语句:自动关闭文件

每次 open() 后都要记得 close(),忘了关闭可能导致文件损坏或内存泄漏。Python 提供了 with 语句,自动帮你关闭:

# 传统写法:需要手动 close
f = open("test.txt", "r")
content = f.read()
f.close()

# with 写法:自动关闭(推荐)
with open("test.txt", "r") as f:
    content = f.read()
# 离开 with 块后,文件自动关闭,不用写 close()
print(content)

在这里插入图片描述

with 的优势:

  1. 代码块结束自动关闭文件,不用记 close()
  2. 即使代码出错(如异常),文件也会被正确关闭
  3. 代码更简洁,缩进清晰

以后写文件读写,一律用 with,忘掉手动 close


六、文件路径

6.1 相对路径与绝对路径

# 相对路径(相对于当前运行目录)
with open("data.txt", "r") as f:
    content = f.read()

# 绝对路径(完整路径)
# Windows
with open("C:\\Users\\test\\data.txt", "r") as f:
    content = f.read()

# Mac / Linux
with open("/home/user/data.txt", "r") as f:
    content = f.read()

Windows 路径用反斜杠 \,但 Python 中 \ 是转义字符,所以要写 \\(双反斜杠),或者在字符串前加 rr"C:\Users\test\data.txt"

6.2 推荐:os.path 处理路径

import os

# 拼接路径(自动适配操作系统)
file_path = os.path.join("data", "scores.txt")
# Windows: data\scores.txt
# Mac/Linux: data/scores.txt

# 检查文件是否存在
if os.path.exists(file_path):
    print("文件存在")
else:
    print("文件不存在")

七、Scratch 积木对照

本章无 Scratch 对照。Scratch 不涉及文件系统操作,程序数据存在浏览器内存中,关闭即丢失。Python 的文件读写是真正的持久化能力,这是从"玩具程序"到"实用工具"的分水岭。


八、综合实战:日记本程序

综合运用文件读写、with 语句、input 交互、字符串格式化、函数封装:

# ========================================
# 日记本程序
# ========================================

import os

DIARY_FILE = "my_diary.txt"

def write_diary():
    """写日记"""
    date = input("请输入日期(如 2026-07-08):")
    weather = input("请输入天气:")
    content = input("请输入日记内容:\n")

    with open(DIARY_FILE, "a", encoding="utf-8") as f:
        f.write(f"{'=' * 30}\n")
        f.write(f"日期:{date}\n")
        f.write(f"天气:{weather}\n")
        f.write(f"内容:{content}\n")
        f.write(f"{'=' * 30}\n\n")

    print(f"✅ 日记已保存到 {DIARY_FILE}")


def read_diary():
    """读日记"""
    if not os.path.exists(DIARY_FILE):
        print("📝 还没有日记记录,先写一篇吧!")
        return

    print(f"\n{'=' * 30}")
    print("      我的日记本")
    print(f"{'=' * 30}")

    with open(DIARY_FILE, "r", encoding="utf-8") as f:
        for line in f:
            print(line, end="")

    print(f"\n{'=' * 30}")


def search_diary():
    """搜索日记"""
    if not os.path.exists(DIARY_FILE):
        print("📝 还没有日记记录")
        return

    keyword = input("请输入搜索关键词:")
    found = False

    with open(DIARY_FILE, "r", encoding="utf-8") as f:
        content = f.read()

    # 按分隔符拆分每篇日记
    entries = content.split("=" * 30)
    for entry in entries:
        if keyword in entry:
            print("=" * 30)
            print(entry.strip())
            found = True

    if not found:
        print(f"未找到包含「{keyword}」的日记")


# 主程序
print("=" * 30)
print("      日记本 v1.0")
print("=" * 30)

while True:
    print()
    print("1. 写日记")
    print("2. 查看所有日记")
    print("3. 搜索日记")
    print("4. 退出")
    print("-" * 25)

    choice = input("请选择(1-4):")

    if choice == "1":
        write_diary()
    elif choice == "2":
        read_diary()
    elif choice == "3":
        search_diary()
    elif choice == "4":
        print("再见!日记已保存在文件中。")
        break
    else:
        print("⚠️ 无效选择")

运行效果:

==============================
      日记本 v1.0
==============================

1. 写日记
2. 查看所有日记
3. 搜索日记
4. 退出
-------------------------
请选择(1-4):1
请输入日期(如 2026-07-08):2026-07-08
请输入天气:晴
请输入日记内容:
今天学会了Python文件读写,很开心!
✅ 日记已保存到 my_diary.txt

分步拆解:

  1. 函数封装:写日记、读日记、搜索日记分别封装成函数,结构清晰
  2. 追加模式:写日记用 "a" 模式,每次新增不会覆盖之前的日记
  3. with 语句:所有文件操作用 with,自动关闭,不用操心
  4. encoding="utf-8":明确指定编码,避免中文乱码
  5. os.path.exists:读文件前先检查是否存在,避免 FileNotFoundError
  6. 搜索功能:用字符串 split() 按分隔符拆分每篇日记,再用 in 匹配关键词

九、常见报错速查表

报错信息出现场景原因解决方法
FileNotFoundError: [Errno 2]open()文件路径不对或文件不存在(r 模式)检查路径,确认文件存在;或用 w/a 模式自动创建
UnicodeDecodeErrorread()文件编码与读取编码不一致(常见中文乱码)open() 时加 encoding="utf-8"
PermissionErroropen()文件被其他程序占用或没有写入权限关闭占用该文件的程序,检查权限
io.UnsupportedOperation: not writablewrite()用 “r” 模式打开却尝试写入改用 “w” 或 “a” 模式打开
ValueError: I/O operation on closed fileread/write文件已 close 后还尝试操作把操作放在 with 块内,或不要提前 close

十、本章小结

本章你掌握了 Python 文件读写的完整流程:

  1. 打开模式——r 只读、w 覆盖写、a 追加写,文件不存在时行为不同
  2. 读取方式——read() 全读、readline() 读一行、readlines() 读成列表、for line in f 逐行遍历
  3. 写入操作——write() 写字符串、writelines() 写多行,都不自动加换行符
  4. with 语句——自动关闭文件,即使出错也不漏关,以后一律用 with
  5. 文件路径——相对路径/绝对路径,用 os.path 处理跨平台路径

文件读写让程序的数据能持久保存,这是从"玩具程序"到"实用工具"的关键一步。

往期回顾:

《Python 零基础入门:从积木到代码》专栏序

零基础学 Python 第1章 | 全平台装环境 + VS Code 配置 + 第一个 Hello World

零基础学 Python 第2章 | print 输出 + 变量赋值 + input 交互输入

零基础学 Python 第3章 | 条件判断:if / elif / else

零基础学 Python 第 4 章 | for 循环与 range():让程序帮你重复干活

零基础学 Python 第 5 章 | while 循环与循环嵌套:让程序看着条件自己干活

零基础学 Python 第 6 章 | 元组与集合:不可变数据与自动去重

零基础学 Python 第7章 | 字典 dict:键值对存储

零基础学 Python 第8章 | 字符串操作与格式化输出

零基础学 Python 第9章 | 函数基础:def、参数与返回值

零基础学 Python 第10章 | 函数进阶:参数灵活用法与作用域

零基础学 Python 第11章 | 匿名函数与高阶函数

下一章预告:文件读写时会遇到各种意外——文件不存在、编码错误、权限不足。下一章学习 try-except 异常处理,让程序遇到错误不崩溃,而是优雅地处理。


文末资源区

资源说明
Python 官方文档 - 文件读写https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files
Python 官方文档 - open()https://docs.python.org/3/library/functions.html#open
Python 官方文档 - os.pathhttps://docs.python.org/3/library/os.path.html
本章完整源码chapter12_all.py(关注梅雅达编程笔记,评论领资料)

每节课都配套课后练习题与完整源码。代码报错、看不懂知识点,可在评论区粘贴问题,逐一解答!
欢迎关注梅雅达编程笔记,持续分享Python零基础学习内容

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐