
练习23:打开和关闭文件
在本练习中,我们将学习如何在Python中打开一个文件,学习不同的使用模式以及它们表示什么。Python有一个内置的open函数,我们将使用它来打开一个文件。open函数接受少量参数作为输入。其中,第一个参数表示你要打开的文件的名称,是唯一强制的参数,其他参数都有一个默认值。调用open时,Python使用底层系统级调用打开一个文件处理程序,并将其返回给调用函数。
通常,打开一个文件可以进行读取或写入操作。如果我们以其中一种操作模式打开文件,则不支持另一种操作模式。读取通常意味着我们从现有文件的开头开始读取,而写入则意味着要么开始一个新文件并从头开始写入,要么打开一个现有文件并向其中添加内容。图2-5显示了Python在打开文件时支持的所有不同模式。

图2-5 读取文件的模式
还有一个不推荐使用的u模式,它在Python3环境中不起任何作用。这里我们必须记住的一点是,即使底层操作系统没有,Python也会始终区分t和b模式。这是因为在b模式下,Python不会尝试解码它正在读取的内容,而是返回bytes对象,而在t模式下,它会尝试解码文本流并返回字符串表示形式。
你可以以读取操作模式打开文件,如下所示:

这是在rt模式下打开的。如果需要,可以以二进制模式打开相同的文件。使用rb模式以二进制模式打开文件:

输出如下:

这是我们如何以写入操作打开文件:

输出如下:

接下来,我们将学习如何关闭打开的文件。关闭已经打开的文件非常重要,因为文件句柄悬空可能会引起许多系统级错误。一旦我们关闭了某个文件,就不能使用该文件句柄对其执行进一步的操作。
1.以二进制模式打开文件:

2.使用close()函数关闭文件:

3.Python为我们提供了一个带有文件句柄的closed标志。如果我们在关闭之前输出它,我们将看到False,而如果我们在关闭之后输出它,那么我们将看到True。如果我们想要检查文件是否正确关闭,那么这就是我们要使用的标志。
使用with语句打开文件
在本练习中,我们将学习Python中的with语句,以及如何有效地在打开和关闭文件的过程中使用它。
with是Python中的复合语句。与任何复合语句一样,with也会影响它所包含的代码的执行。with用于将代码块包装在Python中称为Context Manager(上下文管理器)的范围内。对上下文管理器的详细讨论超出了本练习和本主题的范围,但这足以说明,由于在Python中用于打开文件的open调用实现了上下文管理器,因此如果我们将close调用包装在with语句中,就可以保证其自动执行。
说明
在https://www.python.org/dev/peps/pep-0343/中有关于with的整个Python增强提案(PEP,Python Enhancement Proposal),我们建议你去查看一下。
接下来,我们使用with语句打开一个文件:

输出如下:

如果我们执行前面的代码,将看到第一次输出的结果是False,而第二次输出的结果是True。这意味着一旦脱离with块的控制,文件描述符就会自动关闭。
说明
这是迄今为止打开文件并获取文件描述符的最简洁和最Python化的方法。我们建议你每次使用此模式打开文件。