如何在Python中打开、读取和写入文件

287 阅读8分钟

在使用任何编程语言时,读和写文件都是一种常见的操作。你可以对你的代码进行编程,以便从文件中读取数据或指令,然后也写入数据。这就提高了效率,减少了手工劳动。

Python有一个明确的方法来打开、读取和写入文件。在Python中,文件操作的一些应用包括:读取数据进行算法训练和测试,读取文件创建生成性艺术,报告,以及读取配置文件。

在本教程中,你将学习:

  1. 如何将文件加载到主内存并创建一个文件句柄
  2. 如何使用文件句柄来打开文件进行阅读和写作
  3. 在处理文件时的异常处理

前提条件:

  • 确保你安装了最新的Python版本
  • 熟悉你选择的任何支持Python的文本编辑器
  • 对Python的基本语法有一定的熟悉

要快速访问Python IDE,请查看Replit。你也可以克隆这个 repo 并在 Replit 上运行它。

持久性和如何将文件加载到主内存中

文件驻留在计算机的二级存储器中。二级存储器是持久性的,这意味着当计算机关闭电源时,数据不会被清除。一旦你对一个文件进行修改并保存,这些修改就会永久写入并保存在二级存储器中。

为了处理文件,我们需要先将它们加载到主存储器中。主存储器是临时缓存存储器,在短暂的时间内保存请求的数据。当计算机断电时,这些数据就会丢失:

Files are loaded from secondary memory to the main memory and then processed by the CPU. Once the processing is done, the data is written back to the secondary memory.

文件从二级存储器加载到主存储器,然后由CPU处理。一旦处理完毕,数据就被写回二级存储器。

Python 通过"文件处理程序"与主存中加载的文件进行交互。让我们来详细了解一下文件处理程序。

文件处理程序如何工作

当我们想读或写一个文件时,我们必须首先打开 它。打开一个文件向操作系统发出信号,根据文件名搜索该文件,并确保其存在。

如果打开成功,操作系统就会返回一个文件处理程序。然后我们可以通过文件处理程序与我们的文件进行交互。

文件处理程序不包含数据本身,它只是提供一个处理文件操作的接口:

A file handler provides your program access to data in the secondary memory.

文件处理程序为你的程序提供对二级存储器中数据的访问。

如何打开一个文件

在这个例子中,我们将打开文件daffodils.txt 。注意,这个文件应该和你的Python程序存放在同一个文件夹中。你可以从这个GitHub链接下载该文件daffodils.txt

请看一下这个文件,因为我们将在接下来的例子中使用它的内容。

例子:

fhand = open('daffodils.txt')
print(fhand)

在上面的例子中,如果打开成功,操作系统将在变量fhand 中返回文件柄。默认情况下,你只能读取该文件。

输出:

image-177

文件句柄的输出。

在输出中,我们收到了一个文件句柄,其中name 是文件名,mode 是权限,在我们的例子中是r (代表read )。encoding 是Unicode字符集的编码机制。你可以在这里了解更多关于UTF-8的细节。

异常情况

如果文件不存在,我们会得到这样的一个异常:

Exception when the file is not found.

未找到文件时的异常。

如何打印文件

现在我们有了文件句柄,这意味着我们可以访问该文件。让我们打印该文件,看看它的内容。

例子:

# Get the file handler
fhand = open('daffodils.txt')

# Loop through each line via file handler
for line in fhand:
  print(line) 

输出:

image-179

打印一个文件的内容。

我们能够成功地访问和打印该文件。但是,你是否注意到,我们在每一行之间都有额外的空行?这是有原因的。让我们在下一节看看。

如何处理多余的行空格

新行字符在 Python 中用\n 表示。这个字符在字符串的任何地方都会增加一个新行。

在每一行的末尾都有一个新行字符,将输出打印到下一行。我们可以用repr 方法将其可视化。

根据Python文档repr() 方法返回一个包含对象的可打印表示的字符串。这意味着我们可以看到出现在字符串中的任何特殊字符,如\t or a \n

让我们在下面运行一个例子,看看输出结果:

image-180

使用repr() 来表示字符串。

例子

回到我们的文件,我们可以使用repr() 来检查特殊字符。

# Get the file handler
fhand = open('daffodils.txt')

# Loop through each line via file handler
for line in fhand:
  print(line) 

输出

image-181

在这里我们可以看到幕后发生的事情。

此外,print方法默认会添加一个新行。这意味着使用print,我们会在输出中得到另一个新行。我们可以用两种方法来处理这个额外的行。

方法#1:改变print的默认结束值

下面的片段显示了print 函数的参数。我们可以看到,默认情况下,end 的值是\n 。这意味着每个print语句都会以\n

image-22

源于此:Python文档

我们可以把默认值end='\n' 改为空白,这样我们就不会在每一行的末尾得到一个新行。让我们看看下面的例子来更好地理解:

# By default output would go in separate lines
print("Hello")
print("World")

# Print on the same line because end = ' '
# added single space
print("Hello", end = ' ') 
print("World")

输出:

image-182

使用print() ,在相同和不同的行上打印。

回到我们的主文件,让我们修改一下代码,得到没有多余空行的输出:

# Get the file handler
fhand = open('daffodils.txt')

# Loop through each line and modify the default value of 'end'
for line in fhand:
  print(line, end = '')

输出

在这里我们得到了我们想要的输出!

Print without extra lines using print().

使用print() ,打印没有多余的行。

方法#2:使用rstrip()方法

我们可以使用strip() 方法删除字符串周围的某些字符。

现在我们知道,在默认情况下,文件中的每一行在结尾都有"\n" 。由于我们只关心右边的字符,所以我们将使用rstrip() ,它代表的是right-strip。接下来我们将讨论一个rstrip() 的例子。

你可以在这篇博文中了解更多关于strip() 的方法:

# Get the file handler
fhand = open('daffodils.txt')

# Loop through each line and remove extra line character with rstrip()
for line in fhand:
  line = line.rstrip()
  print(line)

输出:

Print without extra lines using rstrip().

使用rstrip打印没有多余的行()

如何让用户选择一个文件

与其硬编码文件名,我们可以通过让用户选择一个文件来使代码变得动态。

让我们要求用户输入一个文件名。然后我们将计算该文件的行数。

例子

fname = input('Enter the file name: ')
fhand = open(fname)
count = 0
for line in fhand:
     count = count + 1
print('There are', count, 'lines in', fname)

要求用户输入一个文件名。

输出

Request the user to enter the file name.

要求用户输入文件名。

如何在Python中写一个文件

默认情况下,文件处理程序以读模式打开文件。如果我们用以下任何一种模式打开一个文件,我们就可以向该文件写入:

  • w- (Write) 写入一个现有的文件,但删除现有内容。
  • a- (Append)附加到一个现有的文件。
  • x - (Create)创建一个文件,如果该文件存在则返回错误。

如何写到一个文件

注意,如果我们试图用w 标志打开一个已经存在的文件,其内容会被覆盖:

# Open file with mode 'w'
fout = open('flower.txt', 'x')
fout.write("This content would be added and existing would be discarded")
fout.close()

如何追加到一个文件

a 标志附加到现有的内容上,并保留现有的内容:

# Open file with mode 'a'
fout = open('flower.txt', 'a')
fout.write("Now the file has more content at the end!")
fout.close()

如何创建一个文件并写入它

x 模式创建一个文件并向其中添加内容:

# Open file with mode 'x'
fout = open('new-file.txt', 'x')
fout.write("Now the new file has some content!")
fout.close()

如果该文件存在,我们会得到一个像这样的异常:

Traceback (most recent call last):
  File "main.py", line 2, in <module>
    fout = open('flower.txt', 'x')
FileExistsError: [Errno 17] File exists: 'flower.txt'

异常处理

有可能我们请求的文件并不存在。这就会因为异常而使程序爆炸:

image-189

为了使程序更加友好,我们可以在一个try-except 块中处理这个异常。

程序中预计会被炸毁的风险部分被写在try 块中。在代码执行没有异常的情况下,except 块被跳过,程序继续运行。如果发现有异常,则运行except 块,并通过exit 命令优雅地关闭程序:

fname = input('Enter the file name: ')
try:
  fhand = open(fname)
except:
  print('File nout found and can not be opened:', fname)
  exit()
count=0
for line in fhand:
  count = count + 1
print('There are', count, 'lines in', fname)

输出

image-188

使用try-except块处理异常。

总结

知道如何处理文件是编程中的一个基本概念。在本教程中,你学会了如何使用文件处理程序在 Python 中打开文件进行读写。

为了便于参考,我把所有的代码片段和样本文件都包含在这个GitHub repo中。

我希望你觉得这个教程很有帮助。

你最喜欢从本教程中学到的东西是什么?请在Twitter上告诉我。

你也可以在这里阅读我的其他文章。