人人都会AI编程

12.1 文件操作:打开、读写、关闭、文件对象方法

更新时间:2026-07-12

文件操作是任何编程语言都绕不开的基础能力。Python 的文件处理极其简单直接,核心就一个 open() 函数,以及文件对象自带的一组方法。搞懂这一节,读写日志、处理配置文件、数据持久化等需求都能轻松搞定。

打开文件:open() 函数

open() 是最常用的文件入口,基本格式为:

f = open('文件名', '模式', encoding='编码')

常用模式
| 模式 | 含义 |
|------|------|
| 'r' | 只读(默认),文件必须存在,否则报错 |
| 'w' | 只写,若文件存在则清空内容,不存在则创建 |
| 'a' | 追加写,文件存在则在末尾追加,不存在则创建 |
| 'x' | 排他写,若文件已存在则报错,不存在则创建新文件 |
| 'b' | 二进制模式,可与上面组合(如 'rb''wb') |
| 't' | 文本模式(默认),可忽略,如 'rt' 等价于 'r' |
| '+' | 读写模式,如 'r+'(读写,文件必须存在)、'w+'(读写,先清空) |

编码参数 encoding='utf-8' 在读写文本文件时强烈建议显式指定,避免在不同系统间出现乱码。

读取文件内容

打开文件后,可以通过文件对象的方法读取内容:

f = open('data.txt', 'r', encoding='utf-8')

content = f.read()          # 一次性读入全部内容,返回字符串
line = f.readline()         # 读取下一行,保留换行符
lines = f.readlines()       # 读取所有行,返回列表,每行一个字符串

# 常见操作:逐行读取,内存友好
for line in f:
    print(line.strip())     # 去除多余的换行符

f.close()
  • read(size) 可以指定读取的字节/字符数,处理大文件时可分块读取。
  • 逐行遍历for line in f)是最推荐的方式:它不会一次性把所有内容加载到内存,很适合处理大日志文件。
  • readlines() 会一次性返回所有行的列表,文件较大时内存占用高。

写入文件内容

f = open('output.txt', 'w', encoding='utf-8')

f.write('Hello, World!\n')  # 写入字符串,需手动添加换行符
f.writelines(['第一行\n', '第二行\n'])  # 写入可迭代对象,不自动加换行

f.close()
  • write() 会返回实际写入的字符数。
  • writelines() 不会在元素间添加换行符,如有需要应在每个字符串末尾自己加上 '\n'
  • 打开文件写完后 必须关闭,否则可能数据丢失(缓冲区未刷新到磁盘)。

关闭文件与自动管理

文件使用完毕后要调用 f.close() 释放系统资源。但更常见、更安全的方式是使用上下文管理器 with,它会自动关闭文件,即使过程中发生异常也能保证关闭:

with open('data.txt', 'r', encoding='utf-8') as f:
    content = f.read()
# 离开 with 块,自动执行 f.close()

这是 Python 操作文件的 最佳实践,无需手动 close()

文件对象常用方法与属性

除了读写,文件对象还有一些实用方法和属性:

| 方法/属性 | 说明 |
|-----------|------|
| f.readable() | 文件是否可读 |
| f.writable() | 文件是否可写 |
| f.seek(offset, whence) | 移动文件指针位置(whence:0开头,1当前位置,2末尾)|
| f.tell() | 返回当前文件指针位置(字节偏移量) |
| f.flush() | 强制将缓冲区内容写入磁盘 |
| f.truncate(size) | 截断文件到指定大小(字节),常用于写模式 |
| f.fileno() | 返回文件描述符(底层整型数字) |
| f.name | 获取打开的文件名 |
| f.mode | 获取打开模式 |
| f.closed | 文件是否已关闭 |

文件指针示例:

with open('data.txt', 'rb') as f:
    # 定位到文件第10个字节
    f.seek(10)
    data = f.read(5)         # 读取5个字节
    print(f.tell())          # 输出 15

对于二进制文件,seek 可灵活定位;对于文本文件,seek 只能使用相对于开头(0)的位置,或从 tell() 返回的位置。

常见陷阱与建议

  1. 忘记关闭文件:养成用 with 的习惯,避免资源泄露。
  2. 编码问题:始终指定 encoding='utf-8',Windows 系统尤其要注意。
  3. 大文件处理:不要用 read()readlines() 一次加载,用 for line in f 迭代。
  4. 路径分隔符:跨平台路径尽量用 pathlib.Pathos.path.join,而不是硬编码 \/
  5. 同时读写r+ 模式读写指针会移动,需要小心调整 seek,不然很容易覆盖掉后面的内容。

掌握以上内容,日常 90% 的文件操作需求都可以从容应对。更高级的文本格式解析(CSV、JSON 等)将在后续章节展开。