Python 读取文件

想要对文件的内容进行操作,首先需要把内容读取出来。Python 读取文件有以下 2 种方式。

  • 使用 read() 方法。
  • 使用 readlines() 和 readline() 方法。

使用 read() 读取文件

在 Python 中,我们可以使用 File 对象的 read() 方法来一次性读取文件所有内容。而想要实现读取文件的操作,一般都需要 3 步:打开文件、读取文件和关闭文件,如下图所示。

Python 读取文件的流程

语法:

# 第 1 步:打开文件
file = open(path, 'r')

# 第 2 步:读取文件
txt = file.read()

# 第 3 步:关闭文件
file.close()

说明:

open() 函数是 Python 内置函数,它用于打开一个文件。只有把文件打开之后,才能读取文件的内容。参数 path 表示文件的路径,'r' 表示读文件模式(read)。如果采用读文件模式,第 2 个参数 'r' 可以省略。

open() 函数会返回一个 File 对象。你可以把每一个文件都看成一个 File 对象。只有获取到 File 对象,才可以对文件进行各种操作。这个跟 “如果你想要操作一个文件,事先要拿到这个文件” 是一样的道理。

read() 是 File 对象的一个方法,用于读取文件的内容。read() 方法会返回一个字符串,也就是文本的内容。此外,不管是读取文件,还是写入文件,操作之后一定要使用 File 对象的 close() 方法来关闭文件。

接下来,在当前项目下建立一个名为 “data” 的文件夹,然后在该文件夹下面再创建一个 hello.txt,如下图 1 所示。并且在 hello.txt 添加三行文本,如下图 2 所示。

Python 读取文件的项目结构

hello.txt 的内容

示例 1:read() 读取文件

file = open('data/hello.txt', 'r')
txt = file.read()
print(txt)
file.close()

运行结果如下:

Hello Python!
Hello Java!
Hello C++!

分析:

我们把文件的内容看成是一个 “大字符串”,read() 方法返回的就是保存在这个文件中的这个大字符串,这样去理解就很简单了。

open() 函数第一个参数是一个字符串,该字符串就是文件路径。如果路径分割符使用反斜杠(\),那么这个字符串一定要使用原始字符串模式,也就是在字符串前面加上一个 “r” 或 “R”。如果不使用原始字符串,而使用普通字符串的话,就可能会出现转义的问题。

由于这个示例的代码是在 test.py 中,也就是说 “当前工作目录” 就是 test.py 所在的目录。此时 hello.txt 的相对路径是:data/hello.txt,而绝对路径是:D:\python-test\data\hello.txt。对于这个例子来说,下面两种方式是等价的。

# 方式 1:相对路径
file = open('data/hello.txt', 'r')

# 方式 2:绝对路径
file = open(r'D:\python-test\data\hello.txt', 'r')

上面示例只能读取英文文本,如果想要读取中文文本,则需要在 open() 函数中加上一个 encoding = 'utf-8' 的参数,修改后的代码如下。为了避免乱码,以后所有的 open() 函数都建议加上这个参数。

file = open('data/hello.txt', 'r', encoding='utf-8')

有小伙伴可能会问:“file.read() 以及后面介绍的 file.write() 等可以用来操作一个 TXT 文件,那么它们能不能用于操作 Word、Excel、PDF 等格式文件呢?” 其实是不可以的,这是因为 file.read()、file.write() 等只能用于操作纯文本文件,而不能操作二进制文件。

其中,像 TXT、JSON、CSV 等格式文件就是纯文本文件,而 Word、Excel、PDF 等就是二进制文件。如果想要对二进制文件进行读写操作,需要使用对应的模块才行。比如想要读写 Word 文件,需要借助 python-docx 模块。

注意: open() 函数和 file.read()、file.write() 等不一样。不管是纯文本文件,还是二进制文件,都可以使用 open() 函数来打开的。

使用 readlines() 读取文件

前面介绍的 read() 方法是一次性读取文件所有内容。而在 Python 中,我们还可以使用 File 对象的 readlines() 方法来 “逐行” 读取文件中的内容。

想要实现逐行读取文件的操作,也需要 3 步:打开文件、读取文件和关闭文件,如下图所示。

Python 读取文件的流程

语法:

# 第 1 步:打开文件
file = open(path, 'r', encoding='utf-8')

# 第 2 步:读取文件
txt = file.readlines()

# 第 3 步:关闭文件
file.close()

说明:

read() 方法返回的结果是一个字符串,而 readlines() 方法返回的结果是一个列表。其中,每一行的文本就是列表中的一个元素。

示例 2:readlines() 读取文件

file = open('data/hello.txt', 'r', encoding='utf-8')
txt = file.readlines()
print(txt)
file.close()

运行结果如下:

['Hello Python!\n', 'Hello Java!\n', 'Hello C++!']

分析:

在一个文件中,每一行文本后面的换行符本质上是一个字符,即 \n。所以这里会看到前面两个元素后面包含了 “\n” 这个换行符。此外由于 readlines() 方法返回的是一个列表,因此可以使用列表的各种方法来进行操作,请看下面的示例。

示例 3:readlines() 读取每一行文本

file = open('data/hello.txt', 'r', encoding='utf-8')
lines = file.readlines()
for i, line in enumerate(lines):
    content = line.strip('\n')
    result = f'Line {i + 1}: {content}'
    print(result)
file.close()

运行结果如下:

Line 1: Hello Python!
Line 2: Hello Java!
Line 3: Hello C++!

分析:

由于每一行文本最后都有一个换行符,因此这里使用 strip() 方法来去除换行符。实际上,想要读取每一行文本,除了 readlines() 方法,还有一个 readline() 方法。下面 2 种方式是等价的。

# 方式 1:readlines()
file = open('data/hello.txt', 'r', encoding='utf-8')
lines = file.readlines()
for line in lines:
    print(line)
file.close()

# 方式 2:readline()
file = open('data/hello.txt', 'r', encoding='utf-8')
while True:
    line = file.readline()
    if line:
        print(line)
    else:
        break
file.close()

准确来说,readlines() 方法是一次性读取所有内容,然后再使用列表的方式来逐行处理。而 readline() 方法才是真正地逐行读取内容。不过也正是因为 readline() 方法每次只能读取一行,因此处理速度通常会比 readlines() 方法慢很多。

提示: 建议优先使用 readlines() 方法,仅当没有足够内存可以一次读取整个文件时,再去使用 readline() 方法。

强烈推荐的 with 语句

在前面的例子中,我们每次打开文件后,都要小心翼翼地在最后写上一句 file.close()。如果在读取文件的过程中程序突然报错崩溃了,close() 就不会被执行,此时文件就会一直被程序占用。

在 Python 开发中,我们最标准、最优雅的做法是使用 with open(...) as ...: 语句。它会在代码块执行完毕后,自动帮我们安全地关闭文件,再也不用担心忘记写 close() 啦!

# 不推荐
file = open('data/hello.txt', 'r', encoding='utf-8')
txt = file.read()
print(txt)
file.close()


# 推荐
with open('data/hello.txt', 'r', encoding='utf-8') as file:
    txt = file.read()
    print(txt)

对于 with 语句,我们在后面 “Python with 语句” 一节中会详细介绍。

上一篇: Python 文件路径

下一篇: Python 写入文件

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号