python读取文件
python提供内置函数open
实现对文件的io操作。
open函数操作文件和把大象放冰箱里一样分三步,打开-操作-关闭
。
open函数
open(file, mode='r', encoding=None)
打开文件并返回对应的file object
。如果该文件不能打开,则触发OSError
。
-
`file· 包含文件名的字符串,可以是绝对路径,可以是相对路径。
-
mode
一个可选字符串,用于指定打开文件的模式。默认值r
表示文本读。 -
encoding
文本模式下指定文件的字符编码 -
mode
的取值:
字符 | 意义 |
---|---|
'r' |
文本读取(默认) |
'w' |
文本写入,并先清空文件(慎用),文件不存在则创建 |
'x' |
文本写,排它性创建,如果文件已存在则失败 |
'a' |
文本写,如果文件存在则在末尾追加,不存在则创建 |
- 和
mode
组合的字符
字符 | 意义 |
---|---|
'b' |
二进制模式,例如:'rb'表示二进制读 |
't' |
文本模式(默认),例如:rt 一般省略t |
'+' |
读取与写入,例如:'r+' 表示同时读写 |
读文本文件
在当前目录下创建一个名为test.txt的文本文件,(注意编码方式)文件中写入下面的内容:
静夜思
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
基本步骤
# 打开文件 mode=rt,t可以省略
fb = open('test.txt', 'r', encoding='utf-8')
# 读取
content = fb.read()
print(content)
# 关闭文件
fb.close()
输出:
静夜思
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
上面这种操作经常会忘记关闭文件句柄,造成资源浪费,所以处理文件是往往使用with语句进行上下文管理。
with上下文管理
with open('test.txt', 'r', encoding='utf-8') as fb:
content = fb.read()
print(content)
输出:
静夜思
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
with
语句执行完毕会自动关闭文件句柄。
相对路径与绝对路径
进行文件处理时经常会碰到相对路径和绝对路径的问题。
绝对路径好理解,它指定了文件在电脑中的具体位置,以windows电脑为例:
d:\2022\课件\python入门.md
相对路径一般是指相对当前脚本的路径,比如上面的案例中的test.txt
因为和当前脚本在同一个文件夹下,所以可以直接使用test.txt
作为文件名来操作。
也可显式的表达当前路径./test.txt
,./
表示当前目录。
../
表示上级目录,同理../../
表示上上级目录,依此类推。
那什么时候使用相对路径,什么时候使用绝对路径呢?
一般情况下项目本身的资源文件和脚本路径相对固定,为了不影响项目的移植性,必须使用相对路径。
如果需要读取操作系统中固定位置的系统文件一般使用绝对路径。
逐行读取
在读取文本文件时,经常需要按行读取,文件对象提供了多种方法进行按行读取。
readline
从文件中读取一行;如果到达文件末尾, 则 返回一个空的字符串。
with open('test.txt', 'r', encoding='utf-8') as fb:
print(fb.readline())
print(fb.readline())
print(fb.readline())
print(fb.readline())
输出:
静夜思
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
readlines
以列表的形式返回文件中所有的行。
with open('test.txt', 'r', encoding='utf-8') as fb:
content = fb.readlines()
print(content)
输出:
['静夜思\n', '床前明月光,疑是地上霜。\n', '举头望明月,低头思故乡。']
迭代
要从文件中读取行,还可以循环遍历文件对象。这是内存高效,快速的,并简化代码:
# 5星推荐
with open('test.txt', 'r', encoding='utf-8') as fb:
for line in fb:
print(line)
输出:
静夜思
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
读二进制文件
任何文件都可以以二进制读的方式打开,读取test.txt
的二进制内容。
# mode=rb,不需要encoding参数
with open('test.txt', 'rb') as fb:
content = fb.read()
print(content)
输出:
b'\xe9\x9d\x99\xe5\xa4\x9c\xe6\x80\x9d\n\xe5\xba\x8a\xe5\x89\x8d\xe6\x98\x8e\xe6\x9c\x88\xe5\x85\x89\xef\xbc\x8c\xe7\x96\x91\xe6\x98\xaf\xe5\x9c\xb0\xe4\xb8\x8a\xe9\x9c\x9c\xe3\x80\x82\n\xe4\xb8\xbe\xe5\xa4\xb4\xe6\x9c\x9b\xe6\x98\x8e\xe6\x9c\x88\xef\xbc\x8c\xe4\xbd\x8e\xe5\xa4\xb4\xe6\x80\x9d\xe6\x95\x85\xe4\xb9\xa1\xe3\x80\x82'
# 也可以逐行读取,以\n换行符标志
with open('test.txt', 'rb') as fb:
for line in fb:
print(line)
输出:
b'\xe9\x9d\x99\xe5\xa4\x9c\xe6\x80\x9d\n'
b'\xe5\xba\x8a\xe5\x89\x8d\xe6\x98\x8e\xe6\x9c\x88\xe5\x85\x89\xef\xbc\x8c\xe7\x96\x91\xe6\x98\xaf\xe5\x9c\xb0\xe4\xb8\x8a\xe9\x9c\x9c\xe3\x80\x82\n'
b'\xe4\xb8\xbe\xe5\xa4\xb4\xe6\x9c\x9b\xe6\x98\x8e\xe6\x9c\x88\xef\xbc\x8c\xe4\xbd\x8e\xe5\xa4\xb4\xe6\x80\x9d\xe6\x95\x85\xe4\xb9\xa1\xe3\x80\x82'