第8章-处理文件

本章介绍将数据读写到硬盘上的文件的主题。您会发现用Python读写文件非常容易。我们开始吧!

如何读取文件

python有一个内置函数,名为 open 我们可以用来打开一个文件进行阅读。创建文本文件名“test.txt”,内容如下:

This is a test file
line 2
line 3
this line intentionally left blank

下面是几个示例,演示如何使用 open 阅读:

handle = open("test.txt")
handle = open(r"C:\Users\mike\py101book\data\test.txt", "r")

第一个示例将打开一个名为 test.txt 处于只读模式。这是的默认模式 open 功能。注意,我们没有向第一个示例中要打开的文件传递完全限定的路径。python将自动查找运行脚本的文件夹 test.txt .如果找不到它,那么您将收到一个IOERROR。

第二个示例确实显示了文件的完全限定路径,但您会注意到它以“r”开头。这意味着我们希望Python将字符串视为原始字符串。让我们花点时间看看指定原始字符串与常规字符串之间的区别:

>>> print("C:\Users\mike\py101book\data\test.txt")
C:\Users\mike\py101book\data        est.txt
>>> print(r"C:\Users\mike\py101book\data\test.txt")
C:\Users\mike\py101book\data\test.txt

如您所见,当我们不将其指定为原始字符串时,我们会得到一个无效的路径。为什么会这样?好吧,正如您可能从字符串一章中回忆的那样,有些特殊字符需要转义,例如“n”或“t”。在这种情况下,我们看到有一个t“(即制表符),所以字符串会顺服地在我们的路径上添加一个制表符,并为我们将其拧紧。

第二个示例中的第二个参数也是“r”。这说明 open 我们希望以只读模式打开文件。换句话说,它和第一个例子做的是相同的事情,但是它更明确。现在,让我们实际读取文件!

将以下行放入python脚本,并将其保存在与test.txt文件相同的位置:

handle = open("test.txt", "r")
data = handle.read()
print(data)
handle.close()

如果运行此命令,它将打开文件并将整个文件作为字符串读取到 data 变量。然后我们打印数据并关闭文件句柄。您应该总是关闭一个文件句柄,因为您永远不知道其他程序何时会想要访问它。关闭该文件还将有助于保存内存并防止程序中出现奇怪的错误。您可以告诉python一次只读取一行,将所有行读取到python列表中,或者以块的形式读取文件。最后一个选项是非常方便的,当你处理非常大的文件,你不想读取整个东西,这可能会填补PC的内存。

让我们花些时间来研究不同的文件读取方法。

handle = open("test.txt", "r")
data = handle.readline() # read just one line
print(data)
handle.close()

如果运行此示例,它将只读取文本文件的第一行并打印出来。这不太有用,所以让我们试试文件句柄的readlines()方法:

handle = open("test.txt", "r")
data = handle.readlines() # read ALL the lines!
print(data)
handle.close()

运行完这段代码后,您将看到一个打印到屏幕上的python列表,因为这是 读数 方法返回:列表!让我们花点时间来学习如何以较小的块读取文件。

如何逐段读取文件

以块形式读取文件的最简单方法是使用循环。首先我们将学习如何逐行读取文件,然后我们将学习如何一次读取一个千字节。我们将使用 for 第一个示例的循环:

handle = open("test.txt", "r")

for line in handle:
    print(line)

handle.close()

这里我们打开一个只读文件句柄,然后使用 for 循环以循环遍历它。您将发现可以在python中迭代所有类型的对象(字符串、列表、元组、字典中的键等)。很简单,对吧?现在让我们分块来做!

handle = open("test.txt", "r")

while True:
    data = handle.read(1024)
    print(data)
    if not data:
        break

在本例中,我们使用python的 while 循环一次读取文件的千字节。正如您可能知道的,一个千字节是1024个字节或字符。现在让我们假设我们想要读取一个二进制文件,比如PDF。

如何读取二进制文件

读取二进制文件非常容易。您只需更改文件模式:

handle = open("test.pdf", "rb")

所以这次我们把文件模式改为 rb ,也就是说 read-binary .当您从Internet下载PDF文件或将文件从PC传输到PC时,您会发现可能需要读取二进制文件。

用python编写文件

如果您一直在跟踪,您可能会猜到写文件的文件模式标志是什么:“w”和“wb”代表写模式和写二进制模式。让我们来看一个简单的例子,好吗?

CAUTION :当使用“w”或“wb”模式时,如果文件已经存在,将被覆盖而不显示警告!在打开文件之前,可以使用python的 os 模块。见 os.path.exists 段在 第十六章 .

handle = open("test.txt", "w")
handle.write("This is a test!")
handle.close()

那很容易!我们在这里所做的就是将文件模式更改为“w”,然后调用文件句柄的 方法将一些文本写入文件。文件句柄还具有 写入行 方法,它将接受一个字符串列表,然后句柄将按顺序写入磁盘。

使用WITH运算符

python有一个整洁的小内置名为 with 可以用来简化文件的读写。这个 with 操作员创建一个 上下文管理器 在python中,当您完成处理后,它将自动为您关闭文件。让我们看看这是如何工作的:

with open("test.txt") as file_handler:
    for line in file_handler:
        print(line)

的语法 with 接线员有点奇怪,但你会很快接过来的。基本上我们要做的是替换:

handle = open("test.txt")

有了这个:

with open("test.txt") as file_handler:

只要您在 with 代码块。一旦离开该代码块,文件句柄将关闭,您将无法再使用它。是的,你读对了。不再需要将文件句柄显式关闭为 with 操作员自动执行!看看您是否可以更改本章前面的一些示例,以便它们使用 with 方法也是。

捕捉错误

有时,当你处理文件时,会发生不好的事情。文件被锁定,因为其他进程正在使用它,或者您有某种权限错误。当这种情况发生时, IOError 可能会发生。在本节中,我们将介绍如何以常规方式捕获错误,以及如何使用 with 操作员。提示:两者的想法基本相同!

try:
    file_handler = open("test.txt")
    for line in file_handler:
        print(line)
except IOError:
    print("An IOError has occurred!")
finally:
    file_handler.close()

在上面的示例中,我们将通常的代码包装在 try/except 构造。如果发生错误,我们会在屏幕上打印一条消息。请注意,我们还确保使用 finally 声明。现在我们准备好了,看看我们将如何使用 with

try:
    with open("test.txt") as file_handler:
        for line in file_handler:
            print(line)
except IOError:
    print("An IOError has occurred!")

你可能已经猜到了,我们刚刚把 with 以与上一个示例中相同的方式阻塞。区别在于我们不需要 finally 语句作为上下文管理器为我们处理它。

总结

在这一点上,您应该非常精通用Python处理文件。现在您知道了如何使用旧样式和新样式读写文件 with 风格。你很可能会在野外看到这两种风格。在下一章中,我们将学习如何导入Python附带的其他模块。这将允许我们使用预构建模块创建程序。我们开始吧!