嘿,哥们儿/姐们儿!刚学Python,是不是一说到文件读写就有点犯怵?那些 'r'
'w'
'a'
啥的,还有 read()
write()
,跟绕口令似的?别担心,我刚开始那会儿,对着屏幕也是一脸懵圈,感觉手里握着把万能钥匙,却不知道往哪个锁眼里插。今天,咱们就来好好聊聊这事儿,用最“人话”的方式,把你彻底从文件的泥潭里拽出来。
说白了,Python 的文件读写,就是让你的程序能跟硬盘里的文件打交道。想想看,你的程序跑完了,结果得保存下来吧?或者,你需要读取一些配置信息?再或者,你要处理一大堆数据文件?这时候,文件操作就成了绕不过去的坎儿。
最核心、最基础的那个家伙,叫 open()
。没错,就是打开。你想对一个文件做任何事,都得先把它“打开”。就像你要看一本书,总得先把书翻开吧? open()
函数就是干这活儿的。它至少需要俩参数:第一个是文件名(或者文件路径,路径这玩意儿有时候挺折腾人的,绝对路径、相对路径,搞混了文件就“找不到了”),第二个就是你打算怎么“打开”它,也就是咱们常说的“模式”。
模式这东西,有点像你在图书馆借书时告诉管理员你要“阅读”(只看)、“修订”(修改,但得小心别把别人的笔记抹了)还是“复印”(复制一份)。在 Python 里,常见的模式有这么几种:
'r'
:只读(read)。这是最保险的模式。你只能看文件里的内容,不能改、不能加。要是文件不存在,Python 会毫不留情地给你甩个FileNotFoundError
的错误。'w'
:只写(write)。这个模式有点霸道。如果你打开的文件不存在,它就给你新建一个。如果文件已经存在了,嘿嘿,对不起,之前的内容全!部!清!空!然后等着你往里写新的。所以用'w'
模式之前,最好确认一下你是不是真打算把老文件“格式化”掉。'a'
:追加(append)。这个模式就温柔多了。打开文件时,它会把“光标”移到文件末尾。不管文件原来有啥,你写进去的内容都会老老实实地加在最后面,就像写日志一样,只往后面添新条目。如果文件不存在,它也会新建一个。'b'
:二进制模式(binary)。前面说的'r'
'w'
'a'
都是文本模式,Python 会自动处理不同操作系统之间的换行符差异,还会考虑编码问题(敲黑板,编码是个巨坑!一会儿重点说)。但有些文件,比如图片、音频、视频,或者加密文件,它就不是用来给人直接读文字的,它们是二进制数据。这时候就得用'b'
模式,比如'rb'
(只读二进制)、'wb'
(只写二进制)、'ab'
(追加二进制)。在二进制模式下,Python 不会去解析什么字符编码,它就把文件当成一串原始的字节流来处理。
还有一些模式组合,比如 'r+'
表示可读写,'w+'
也是可读写但会清空原有内容,'a+'
也是可读写但写入是追加。不过刚开始,先把 'r'
, 'w'
, 'a'
搞明白就够用了。
好了,文件打开了,接下来就是读取或者写入了。
读取文件:
文件对象打开后,你可以用几种方法把内容“拿出来”:
file.read(size=-1)
:一股脑儿全读出来!如果没有指定size
或者指定为负数(默认就是-1),它会尝试读取文件里的所有内容,然后返回一个字符串(文本模式下)或者字节串(二进制模式下)。用这个要小心,如果文件太大,你的内存可能吃不消,程序分分钟给你罢工。file.readline(size=-1)
:一行一行读。它会从当前位置开始,读到换行符或者到达文件末尾为止,返回一行内容。如果指定了size
,它最多读这么多字符/字节。通常在处理大文件时,我们会循环调用readline()
来避免一次性加载过多内容。file.readlines()
:把所有行都读出来,放在一个列表里。列表的每个元素就是文件里的一行(包括换行符)。这个跟read()
有点像,都是一次性加载,如果文件巨大,同样有内存风险。
但你知道吗?在文本模式下,文件对象本身是可迭代的!这意味着你可以直接用 for line in file:
来遍历文件的每一行,这通常是处理大文件最优雅、内存效率最高的方式。
写入文件:
当你用 'w'
或 'a'
模式打开文件后,就可以往里写入内容了:
file.write(string)
:写入一个字符串(文本模式)或字节串(二进制模式)。注意,write()
不会自动给你加换行符,如果你想每写一次就换行,得手动在字符串末尾加上'\n'
。file.writelines(list_of_strings)
:写入一个包含字符串(或字节串)的可迭代对象(比如列表)。它会把列表里的每个元素依次写入文件,但同样不会自动加换行符。
写完东西,或者读完东西,记得要关闭文件!file.close()
。这是非常重要的步骤。如果文件没关闭,你写入的内容可能还在程序的内存里没真正写到硬盘上,而且操作系统也会一直占用这个文件资源。忘记关闭文件,轻则数据丢失,重则程序出错,甚至影响其他程序访问这个文件。
但是!重点来了!手动调用 close()
很容易忘记。尤其是在程序运行过程中,如果出现了异常,close()
可能就永远执行不到了。这怎么办?Python 提供了一个超级无敌好用的机制,叫上下文管理器(Context Manager),配合 with open(...) as ...:
语法使用。
用 with open('my_file.txt', 'r') as f:
这样的句式,Python 会保证不管中间代码跑得顺不顺,有没有出错,在 with
块结束的时候,文件都会被自动关闭。这简直是解放双手,代码更安全可靠。强烈建议!强烈推荐!以后读写文件,请务必用 with open
!除非你有极其特殊的需求,否则就把它当成写文件操作的“标准姿势”。
举个例子,你想读一个叫 hello.txt
的文件内容:
“`python
try:
with open(‘hello.txt’, ‘r’, encoding=’utf-8′) as f:
content = f.read()
print(content)
except FileNotFoundError:
print(“哎呀,文件没找到!”)
except Exception as e:
print(f”读文件时出了点小问题:{e}”)
“`
看到没?用了 with
,文件关闭的事儿压根儿不用你操心了。加个 try...except
是个好习惯,程序没那么容易因为文件不存在或者没权限而崩溃。
再比如,你想往 output.txt
里写几行字:
“`python
lines_to_write = [“第一行内容。\n”, “这是第二行。\n”, “最后一行,不带换行也行。\n”]
try:
with open(‘output.txt’, ‘w’, encoding=’utf-8′) as f:
f.write(“先写点啥。\n”)
f.writelines(lines_to_write)
print(“文件写入成功!”)
except Exception as e:
print(f”写文件时遇到麻烦了:{e}”)
“`
这里用了 'w'
模式,如果 output.txt
之前有内容,执行这段代码后就都没了。
说到编码,这可是个老大难问题。你的文本文件,在硬盘上存的其实是一堆数字(二进制数据)。怎么把这些数字还原成我们能看懂的文字?这就需要编码和解码规则。不同的规则就是不同的编码格式。比如早年的 GBK、Big5,现在的 UTF-8。
如果你的文件是用 GBK 保存的,但你用 encoding='utf-8'
去读,或者反过来,用 UTF-8 保存的你用 GBK 去读,就会出现乱码,俗称“ mojibake”。那画面太美,全是方块、问号或者奇奇怪怪的符号。
现在,最通用的编码是 UTF-8。它支持世界上绝大多数语言的字符,兼容性最好。所以,我的经验是,读写文本文件时,尽量 总是 指定 encoding='utf-8'
。尤其是你在处理别人给你的文件,或者你的程序可能在不同操作系统上传来传去的时候,指定 UTF-8 能帮你省掉无数麻烦。除非你明确知道文件是其他编码,并且有特殊原因必须用那种编码处理。
总结一下,python怎么读写文件这事儿,其实就是围绕着 open()
函数和文件对象展开。记住几个关键点:
- 用
open()
打开文件,指定文件名和模式 ('r'
,'w'
,'a'
等)。 - 选择合适的读 (
read()
,readline()
,readlines()
) 或写 (write()
,writelines()
) 方法。 - 强烈使用
with open(...) as ...:
结构,让Python帮你自动关闭文件。 - 文本文件读写,永远考虑编码,推荐使用
encoding='utf-8'
。 - 处理图片、音频等非文本文件时,使用二进制模式 (
'rb'
,'wb'
等)。 - 别忘了异常处理,文件可能不存在、没权限等。
你看,好像也没那么复杂,对吧?关键是多练,多踩坑(哈哈,开玩笑,尽量避开),慢慢地,文件读写就会成为你的 Python 工具箱里一个顺手的扳手。当你能自如地让程序从文件里捞数据,或者把计算结果整整齐齐地存进文件,那种成就感,嘿!动手试试吧!
评论(0)