open() 函数的第二个参数是模式字符串,它决定了你能对文件做什么,以及数据以什么形式读写。模式选错,轻则报错,重则误删数据,所以必须搞清楚。
基础模式字符
| 字符 | 含义 |
|------|------|
| r | 读取(默认),文件必须存在,否则报 FileNotFoundError |
| w | 写入,会清空已有内容,文件不存在则创建 |
| x | 排他性创建,文件已存在则报错,适合避免意外覆盖 |
| a | 追加,从文件末尾继续写入,文件不存在则创建 |
| b | 二进制模式,与上面字符组合使用(如 rb、wb) |
| t | 文本模式(默认),与上面字符组合使用(如 rt 就等于 r) |
| + | 更新模式,同时支持读写,与 r/w/a 组合使用 |
实际使用中,模式字符串由这些字符组合而成。最常用的几个组合是:
1. 只读:'r' (默认文本模式)
with open('data.txt', 'r', encoding='utf-8') as f:
content = f.read() # 一次性读入全部内容
# 或逐行读取
for line in f:
print(line.strip())
- 文件不存在会报错。
- 不写
'r'和't',因为它们是默认值,open('data.txt')等价于open('data.txt', 'rt')。
2. 只写:'w'
with open('output.txt', 'w', encoding='utf-8') as f:
f.write('Hello\n')
f.write('World\n')
- 谨慎:每次用
'w'打开,文件的已有内容立刻被清空。 - 文件不存在会自动创建。
- 适合从头生成新文件。
3. 追加:'a'
with open('log.txt', 'a', encoding='utf-8') as f:
f.write(f'错误发生时间:{datetime.now()}\n')
- 写入的数据会追加到文件末尾,不清空原有内容。
- 文件不存在会自动创建。
- 常用于日志文件、持续记录的监控数据。
4. 二进制模式:'rb' / 'wb'
处理图片、音频、视频、PDF 等非文本文件,必须用二进制模式。
# 复制图片
with open('source.jpg', 'rb') as src, open('copy.jpg', 'wb') as dst:
dst.write(src.read()) # 按字节复制
- 二进制模式下,读取返回的是
bytes对象,而不是字符串。 - 不能指定
encoding参数,因为二进制数据就是原始字节流。
5. 读写组合:'r+' / 'w+' / 'a+'
'r+':读写模式,文件必须存在,写入从文件开头覆盖,不会清空原内容。'w+':读写模式,但会清空已有文件;文件不存在则创建。'a+':读写模式,写入追加到末尾,可以读取到原内容,但读取位置需要手动定位(因为打开时指针在末尾)。
with open('data.txt', 'r+', encoding='utf-8') as f:
content = f.read()
f.write('\n追加一行')
实际项目中,'r+' / 'w+' 用得较少,因为同时读写时指针位置容易混乱。多数场景下,先读后写、或先写后读、用不同句柄操作更清晰。
文本模式 vs 二进制模式的选择
- 文本模式(
t):默认,读写数据是字符串,会根据平台自动处理换行符(Windows 为\r\n,Linux/macOS 为\n),需要指定编码(如utf-8)。 - 二进制模式(
b):读写原始字节,不做换行符转换,无法指定编码。所有非文本文件都必须用二进制模式,否则图片文件会被破坏。
简单记忆:只要你读写的是 .txt、.csv、.json 这类纯文本文件,就用文本模式;处理 .jpg、.pdf、.zip 等文件,直接用二进制模式。