Python 中的文件处理
- Python 中的文件处理
- 文件操作
- 打开和关闭文件
- 读写文件
- 使用上下文管理器(Context Manager)
- 在多个文件上操作
Python 中的文件处理
从文件读取数据或向文件写入数据是任何编程语言支持的基本操作之一。Python为处理文件操作提供了广泛的支持,这些操作大多在其标准库中可用。在本节中,我们将讨论核心文件操作,如打开文件、关闭文件、从文件读取、写入文件、使用上下文管理器进行文件管理,以及使用Python标准库用一个句柄打开多个文件。
文件操作
文件操作通常从打开文件开始,然后读取或更新该文件中的内容。核心文件操作如下:
打开和关闭文件
要对文件进行读取或更新操作,我们需要一个指向文件的指针或引用。文件引用可以通过使用内置 open
函数打开文件来获得。该函数返回对文件对象的引用,在某些文献中也称为文件句柄。使用 open
函数的最低要求是提供带有绝对路径或相对路径的文件名。一个可选参数是访问模式,用于指示以哪种模式打开文件。访问模式可以是读取、写入、追加或其他。访问模式选项的完整列表如下:
r
:该选项用于以只读模式打开文件。如果没有提供访问模式选项时,该选项为默认选项:f = open('abc.txt') #和下面的打开方式是等价的 f = open('abc.txt', 'r')
t
:该选项用于用文本模式打开文件,这是默认的打开方式;f = open('abc.txt') f = open('abc.txt', 'r') # 上面两种打开方式,等价于下面的打开方式: f = open('abc.txt', 'rt')
b
:该选项用于用二进制方式打开文件;
注意: 打开文件的文本模式和二进制模式的概念来自于C
语言,这里已罗列的和将要罗列的读、写和添加等打开模式,也是来自于C
语言。文本模式和二进制模式在Linux
和Mac
上没有区别。在Windows
上的区别是,在写文件时,文本模式要把"\n"
转换为\r\n
;在读文件时,把"\r\n"
转换为\n
。此外,有的C
语言运行库,还会有字符编码转换功能,比如微软的C
运行库就有这样的功能。
-
a
: 该选项用于打开文件,在文件末尾添加内容:f = open('abc.txt', 'a')
-
w
:该选项用于打开文件以进行写入。如果文件不存在,它会创建一个新文件。一个新文件。如果文件存在,该选项将覆盖文件,文件中的任何现有内容都将被销毁。该文件中的任何内容都将被销毁:f = open('abc.txt', 'w')
-
x
:该选项用于打开一个文件进行独占写入。如果文件已经存在、 则会出错:f = open('abc.txt', 'x')
-
+
:该选项用于打开文件进行读和写,要和r
或w
配合使用,w+
和w+b
会在读写前把文件内容销毁,r+
和r+b
不会销毁文件内容:f = open('abc.txt', 'r+') f = open('abc.txt', 'w+')
如果是用文本模式打开文件,还可以在打开文件时指明文件中字符的编码。如果不指明,这个编码则依赖于当前的系统的当前编码;如果是用二进制模式打开文件,则不能指明编码。下面是把文件中字符当成utf-8
编码打开文件读和写:
f = open('abc.txt', mode = 'r', encoding = 'utf-8')
f = open('abc.txt', mode = 'w', encoding = 'utf-8')
打开文件后,要关闭文件,下面是代码:
f = open('abc.txt')
f.close()
一旦关闭文件,操作系统将释放与文件实例和锁(如果有的话)相关的资源,这是任何编程语言的最佳实践。
读写文件
以访问模式 r
打开文件,然后使用下面任何其中一种读取方法,即可读取文件。下面总结了可用于读取操作的不同方法:
read(n)
:这个方法用于从文件中读取n
个字符;readline()
:这个方法用于从文件中读取一行;readlines()
:这个方法用于从文件中读取所有的行。
同样,一旦文件以适当的访问模式打开,我们就可以追加或写入文件。与追加文件相关的方法如下:
write(x)
:这个方法将字符串或字节序列写入文件,并返回文件中添加的字符数;wrtelines(lines)
:该方法将一系列行写入文件。
在下一个代码示例中,我们将创建一个新文件,向其中添加几行文本,然后使用前面讨论过的读取操作读取文本数据:
f1 = open('myfile.txt', 'w')
f1.write('我是一只小鸭子,依呀依呀哟。\n')
lines = ["是在春天的时候我就离开了你\n", "那时灿烂缤纷的四月披上了彩衣\n", "就连忧郁的土星也含笑翩翩起舞\n", "天下万物处处都注满了生机\n"]
f1.writelines(lines)
f1.close()f2 = open('myfile.txt', 'r')
print(f2.read(4))
print(f2.readline(), end="")
print(f2.readline(), end="")f2.seek(0)
for line in f2.readlines():print(line, end="")f2.seek(0)
for line in f2:print(line, end="")
f2.close()
以下是上面代码的输出结果:
我是一只
小鸭子,依呀依呀哟。
是在春天的时候我就离开了你
我是一只小鴫子,依呀依呀哟。
是在春天的时候我就离开了你
那时灿烂缤纷的四月披上了彩衣
就连忧郁的土星也含笑翩翩起舞
天下万物处处都注满了生机
我是一只小鴫子,依呀依呀哟。
是在春天的时候我就离开了你
那时灿烂缤纷的四月披上了彩衣
就连忧郁的土星也含笑翩翩起舞
天下万物处处都注满了生机
这里要注意的是,当读过一个文件,要重新从头读的时候,要用seek(0)
方法,把文件指针重新移动到文件开头。
使用上下文管理器(Context Manager)
在任何编程语言中,正确、公平地使用资源都至关重要。文件处理程序和数据库连接就是许多例子中的两个,它们在处理完对象后不及时释放资源是常见的。如果完全不释放资源,就会导致内存泄漏,影响系统性能,最终可能导致系统崩溃。
为了解决内存泄漏和及时释放资源的问题,Python提出了上下文管理器的概念。上下文管理器旨在根据设计精确地保留和释放资源。当上下文管理器与with关键字一起使用时,with
关键字后的语句应返回一个必须实现上下文管理协议的对象。此协议要求返回的对象实现两个特殊方法。这些特殊方法如下:
.__enter__()
:该方法与with
关键字一起调用,用于根据with
关键字后面的语句预留所需的资源;.__exit__()
:该方法在with
块执行后调用,用于释放.__enter__()
方法中保留的资源。
例如,当使用上下文管理器 with
语句(块)打开文件时,无需关闭文件。文件打开语句将返回文件处理程序对象,该对象已执行了上下文管理协议,一旦 with
语句块执行完毕,文件将自动关闭。使用上下文管理器写入和读取文件的代码示例修订版如下:
with open('myfile.txt', 'w') as f1:f1.write('我是一只小鸭子,依呀依呀哟。\n')lines = ["是在春天的时候我就离开了你\n", "那时灿烂缤纷的四月披上了彩衣\n", "就连忧郁的土星也含笑翩翩起舞\n", "天下万物处处都注满了生机\n"]f1.writelines(lines)with open('myfile.txt', 'r') as f2:print(f2.read(4))print(f2.readline(), end="")print(f2.readline(), end="")f2.seek(0)for line in f2.readlines():print(line, end="")f2.seek(0)for line in f2:print(line, end="")
输出结果和上面一致。使用了上下文管理器后,代码更加清晰了。建议使用上下文管理器打开和处理文件。
在多个文件上操作
Python 支持同时打开和操作多个文件。我们可以用不同的模式打开这些文件并对其进行操作。文件数量没有限制。下面的示例代码以读取模式打开两个文件,并以任意顺序访问文件:
with open('myfile1.txt', 'w') as f1, open('myfile2.txt', 'w') as f2:f1.write('我是一只小鸭子,依呀依呀哟。\n')lines = ["是在春天的时候我就离开了你\n", "那时灿烂缤纷的四月披上了彩衣\n", "就连忧郁的土星也含笑翩翩起舞\n", "天下万物处处都注满了生机\n"]f2.writelines(lines)with open('myfile1.txt', 'r') as f1, open('myfile2.txt', 'r') as f2:print(f1.read(4))print(f1.readline(), end="")print(f1.readline(), end="")for line in f2.readlines():print(line, end="")f2.seek(0)for line in f2:print(line, end="")
下面是输出结果:
我是一只
小鸭子,依呀依呀哟。
是在春天的时候我就离开了你
那时灿烂缤纷的四月披上了彩衣
就连忧郁的土星也含笑翩翩起舞
天下万物处处都注满了生机
是在春天的时候我就离开了你
那时灿烂缤纷的四月披上了彩衣
就连忧郁的土星也含笑翩翩起舞
天下万物处处都注满了生机
还可以把一个文件的内容读出来,然后写到另一个文件里去:
# 把 myfile1.txt 的内容读出来,然后写到 myfile2.txt 里。
with open('myfile1.txt', 'w') as f1:lines = ["是在春天的时候我就离开了你\n", "那时灿烂缤纷的四月披上了彩衣\n", "就连忧郁的土星也含笑翩翩起舞\n", "天下万物处处都注满了生机\n"]f1.writelines(lines)with open('myfile1.txt', 'r') as f1, open('myfile2.txt', 'w') as f2:for line in f1.readlines():f2.write(line)with open('myfile2.txt', 'r') as f:for line in f:print(line, end="")
Python还有一个更优雅的解决方案,可以使用fileinput
模块对多个文件进行操作。此模块的输入函数可以接收多个文件的列表,然后将所有这些文件视为单个输入。下面给出了使用fileinput
模块的带有两个输入文件myfile1.txt
和myfile2.txt
的示例代码:
import fileinputwith open('myfile1.txt', 'w') as f1, open('myfile2.txt', 'w') as f2:lines = ["是在春天的时候我就离开了你\n", "那时灿烂缤纷的四月披上了彩衣\n", "就连忧郁的土星也含笑翩翩起舞\n", "天下万物处处都注满了生机\n"]f1.writelines(lines)liens = ["可是无论小鸟的歌唱,或万紫\n","千红、芬芳四溢的一簇簇鲜花,\n", "都不能使我诉说夏天的故事,\n", "或从烂熳的山洼把它们采掐:\n"]f2.writelines(liens)with fileinput.input(files = ("myfile1.txt", "myfile2.txt")) as fin:for line in fin:print(line, end="")
输出结果是:
是在春天的时候我就离开了你
那时灿烂缤纷的四月披上了彩衣
就连忧郁的土星也含笑翩翩起舞
天下万物处处都注满了生机
可是无论小鸟的歌唱,或万紫
千红、芬芳四溢的一簇簇鲜花,
都不能使我诉说夏天的故事,
或从烂熳的山洼把它们采掐:
可以看到,读出的内容是按照打开文件的先后顺序排列的。通过这种方法,我们得到一个按顺序对多个文件进行操作的文件句柄。这方便多了。
<完>