Python文件打开模式详解:r、w、a及读写权限与指针操作

七月
七月
发布时间:2026-10-13| 4人浏览过
原创

本文详细解析Python中文件打开模式r、w、a及其组合r+、w+、a+的行为差异,重点探讨读写权限、文件创建条件及指针位置对读取结果的影响。通过实例说明因指针位于文件末尾导致的读取空值或乱码问题,并提供seek重置指针与with语句规范操作的解决方案,帮助开发者避免常见文件IO错误。

本文通过具体实例深入解析Python中文件打开的各种模式,旨在帮助读者清晰理解不同模式的特性与适用场景,供学习参考。

Python文件打开模式基础辨析

首先需排除因文件打开模式选择错误导致的问题。

理解基础模式:r代表只读,r+代表读写但不创建新文件;若文件不存在,r模式会报错。

w代表新建并只写,w+代表新建并读写。这两种模式在打开文件时,都会将原有文件内容清空。

注意以w模式打开的文件无法读取内容,而w+模式则支持读写操作。

进一步辨析w+与r+的核心区别。

r+模式允许读写,但如果目标文件不存在,程序会报错;而w+模式同样允许读写,若文件不存在则会自动创建新文件。

接着分析r+与a+模式的区别。


fd = open("1.txt",'w+')
fd.write('123')
fd = open("1.txt",'r+')
fd.write('456')
fd = open("1.txt",'a+')
fd.write('789')

观察以下代码执行后的输出结果。

456789

上述结果说明,使用r+模式写入时,新内容覆盖了文件原有的部分数据。

当以a或a+模式打开文件时,采用的是附加(追加)方式。

a模式为附加写方式,不支持读取;a+模式为附加读写方式,支持读取。

使用'U'标志打开文件时,所有行分割符在通过Python输入方法(如read()系列)返回时,都会被统一替换为换行符\n。'rU'模式同时也支持'rb'二进制选项。

r模式和U模式均要求目标文件必须已经存在,否则无法打开。

w模式和a模式属于不可读的打开方式。

若文件不存在会自动创建新文件的方式包括:a、a+、w、w+。


>>> fd=open(r'f:\mypython\test.py','w') #只读方式打开,读取报错
>>> fd.read()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
IOError: File not open for reading
>>> fd=open(r'f:\mypython\test.py','a')#附加写方式打开,读取报错
>>> fd.read()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
IOError: File not open for reading
>>>

文件指针导致的读写异常与解决

其次,解决正确读写方式下出现乱码的问题。


>>> fd=open(r'f:\mypython\test.py','a+')
>>> fd.write('123')
>>> fd.read()
>>> fd.close()

在调用close之前手动打开文件,发现没有写入内容;而在close之后手动打开文件,则看到乱码:123嚅?。

原因分析主要涉及指针位置问题。open()以a+模式开启一个附加读写模式的文件,由于是a特性,文件指针位于文件末尾。此时如果执行read(),Python发现指针位置即为EOF(文件结束符),因此读取到空字符串。

在写入“123”之后,指针位置变为4,仍处于文件尾,内存中的文件状态显示为123[EOF]。

但在执行read()时,Python仍然尝试在磁盘文件上,将指针从文件头向后移动3个字符,然后读取直到EOF为止。

这意味着,实际上你跳过了该文件真正的EOF,对硬盘底层数据进行了dump操作,一直dump到了从前存盘文件的[EOF]位置。因此,最后得到了一些意想不到的随机乱字符,而非单纯的编码错误导致的乱码。

解决方案:在读取之前,将指针重置为文件头(注意:如果读取之后重置指针再读,操作无效)。


>>> fd=open(r'f:\mypython\test.py','a+')
>>> fd.seek(0)
>>> fd.read()
'123'#顺利读出

读取空字符的原因与seek重置

第三类问题:文件明明有内容,却读出了空字符。


>>> fd=open(r'f:\mypython\test.py','w+') #清空内容,重新写入
>>> fd.write('456')
>>> fd.flush()#确定写入,此时文件内容为“456”
>>> fd.read()
'' #读出空

原因同样是指针问题:写入操作后,指针指向文件末尾[EOF],因此直接读取会得到空结果。

解决方案一:调用close后重新打开文件,此时指针位于文件开头。(r、r+、a+、U模式均可,注意避免使用w、w+、a模式)。


>>> fd.close()
>>> fd=open(r'f:\mypython\test.py','a+')
>>> fd.read()
'456'
>>> fd.close()
>>> fd=open(r'f:\mypython\test.py','r+')
>>> fd.read()
'456'
>>> fd.close()
>>> fd=open(r'f:\mypython\test.py','r')
>>> fd.read()
'456'
>>> fd.close()
>>> fd=open(r'f:\mypython\test.py','U')
>>> fd.read()
'456'

解决方案二:调用seek函数将指针指向文件开头。


>>> fd=open(r'f:\mypython\test.py','w+')
>>> fd.write('456')
>>> fd.seek(0)
>>> fd.read()
'456'

关于seek函数的用法。

seek(offset[, whence]) ,其中offset是相对于某个位置的偏移量。位置由whence参数决定,默认whence=0,表示从文件开头起算;whence=1,表示从当前位置算起;whence=2表示相对于文件末尾移动,通常此时offset取负值。

规范关闭文件与with语句使用

最后,务必记得调用close()关闭文件。

当我们写入文件时,操作系统通常不会立即将数据写入磁盘,而是先存入内存缓存,待空闲时再慢慢写入。只有调用close()方法时,操作系统才保证将未写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写入了一部分,剩余部分丢失。因此,推荐使用with语句来确保文件安全关闭:


with open('/Users/michael/test.txt', 'w') as f:
  f.write('Hello, world!')

参考评论区补充:对于'r+'模式,如果先读取内容再写入,行为类似于追加模式;如果直接写入内容,则是覆盖模式。

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python文件与目录操作技巧汇总》、《Python文本文件操作技巧汇总》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》。

希望本文所述的Python文件操作技巧对大家有所帮助。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。