文件操作概述
今天我将探索怎样使用Python 操作文件,以及和文件进行通信。这些天我探索并且分享了Python中的多个概念以及Python中的一些编程最佳实践。但是,我们的程序因为各种各样的原因经常需要和外部进行通信,比如从excel,CSV或者pdf文件中读取数据,转化和压缩图片,从text文件中提取数据,从数据库中读取数据以及其他很多很多。与外部的交互使用I/O或者输入-输出操作进行的。
文件帮助我们将数据永久的存储在系统中。当我们写程序管理数据时,这些数据被临时的存储在机器的RAM中,当电脑关机的时候会被清除。要想长久的存储数据,它们需要被存储在数据库或者文件系统中,以保证数据可以后期使用。
文件基于它们的内容可以广泛的分成两类:
- 二进制(也成为富文本)
- Text
如果你对这两种文件类型感兴趣,想知道更多相关的内容,可以点击看这篇不错的文章
Python提供了一个内置的open函数来打开任意文件。任何文件都需要先打开才能读取数据或者写入数据。在Python中从文件中读取数据是很容易的。
我使用REPL作为平台来试验本文提供的所有代码段。
打开文件
我创建了一个test.txt文件并写入了一些假数据来进行测试。
# test.txt I am learning python.复制代码
现在这个文件中的内容能够使用Python读取,像这样
main.py
content = open('test.txt') output = content.read() print(output) # I am learning python.复制代码
当我们使用open函数打开文件的时候,也可以指定打开的模式。默认是r(读模式)。我们还可以指定文件是需要以文本模式还是二进制模式打开。
模式 | 描述 |
---|---|
r | 以只读方式打开. (默认)【译者注:文件的指针将会放在文件的开头】 |
w | 以写入方式打开. 如果文件不存在就创建新文件,如果文件存在就重写该文件 |
x | 新建一个文件,如果文件存在则报错 |
a | 打开一个文件并在尾部进行追加,如果文件不存在则新建文件 |
t | 以文本模式打开. (默认) |
b | 以二进制模式打开. |
+ | 打开文件并更新 (读取和写入) |
打开文件时我们也可以指定编码格式。默认格式是utf-8
关闭文件
对文件执行完操作关闭文件是很重要的,它会释放与文件相关的内存空间。
main.py
content = open('test.txt', mode='r') output = content.read() print(output) content.close()复制代码
上面的代码中可以加入try-except finally语句,这能确保操作执行过程中出现任何错误,文件都会被关闭。
main.py
try: content = open('test.txt', mode='r') output = content.read() print(output)except FileNotFoundError as error: print(f'file not found {error}')finally: content.close()复制代码
Python提供了一个好用的执行文件打开操作的语法,使用with语句。一旦操作结束它会自动关闭文件。
main.py
with open('test.txt', mode='r') as content: output = content.read() print(output) # I am learning python.复制代码
写入文件
Python提供了一个write方法给文件写入数据。文件需要以w模式打开用来写入文件。需要注意的是,使用w模式会重写文件的内容。如果需要内容追加,应该使用a模式。如果文件不存在,则先创建后写入。
main.py
with open('test.txt', mode='w', encoding='utf-8') as my_file: my_file.write('This is the first line\n') # \n 是用来换行my_file.write('This is the second line\n') my_file.write('This is the third line')复制代码
main.py
with open('test.txt', mode='a', encoding='utf-8') as my_file: my_file.write('This text will be appended')复制代码
另一种方式是使用writelines方法。它可以提供一个列表。
with open('test.txt', mode='w', encoding='utf-8') as my_file: my_file.writelines(['First line', '\n', 'Second Line'])复制代码
读取文件
Python提供了很多读取文件的方法。文件需要以r模式打开,如果我们需要同时执行读取和写入操作则需要使用r+模式。read方法接收一个size参数,它是读取字节的总数。如果这个size没有提供,则会读取整个文件。
main.py
with open('test.txt', mode='r', encoding='utf-8') as my_file: content = my_file.read() print(content)复制代码
还有一个tell方法,它是告诉我们当前正在读取的文件的游标位置。
seeek方法用于将游标移到文件中指定的位置。
main.py
with open('test.txt', mode='r', encoding='utf-8') as my_file: my_file.seek(0) # 将游标移到文件最开始的位置print(my_file.tell()) # 输出文件游标content = my_file.read() print(content)复制代码
如果文件中有很多行,读取文件最有效的方式是使用循环。
main.py
with open('test.txt', mode='r', encoding='utf-8') as my_file:for line in my_file: print(line)复制代码
除此之外,Python还提供了两个方法,readline和readlines
readline读取文件时遇到新的行(\n)则停止
readlines返回包含所有行的列表
Python文件方法
下面是Python中文件方法的完整列表
方法 | 描述 |
---|---|
close() | 关闭打开的文件,如果文件已经关闭了则不会产生任何影响 |
detach() | 将底层二进制缓冲区与TextIOBase分离并返回。 |
fileno() | 返回一个整型的文件描述符 |
flush() | 刷新文件内部缓冲 |
isatty() | 如果文件流是交互式的,则返回True |
read(n) | 从文件中读取指定的字节数。如果指定为负数或者没有指定则读取所有 |
readable() | |
readline(n=-1) | 读取并返回文件中的一行。如果指定,最多读取n个字节。 |
readlines(n=-1) | 读取并返回文件中的行列表。如果指定,最多读取n个字节/字符。 |
seek(offset,from=SEEK_SET) | 将文件位置更改为偏移字节,引用from (start, current, end)。 |
seekable() | |
tell() | |
truncate(size=None) | 将文件流调整为字节大小。如果未指定size,则调整为当前位置。 |
writable() | |
write(s) | 将字符串s写入文件,并返回写入的字符数。 |
writelines(lines) |
有趣的练习
让我们尝试构建一个语言转换程序,它能够读取一个英文内容的文件,并使用不同语言创建该文件的新翻译版本。
为了这个练习,我们将使用一个叫做 Translate的PyPI上的第三方包。有了这个包的帮助,我们可以做到离线翻译。
首先,这个包需要被下载。因为我正在使用REPL,我将把它添加到REPL中的packages部分。如果使用本地项目的话,我们可以在控制台使用pip进行下载。
创建一个名为quote.txt的文件,并写入一句名言:
quote.txt
If you can't make it good, at least make it look good. - Bill Gates复制代码
现在我们生成这个句引言的两个翻译版本。一种是西班牙语,文件命名为quote-es.txt,另一种是法语,文件命名为quote-fr.txt
main.py
from translate import Translator spanish_translate = Translator(to_lang="es") french_translate = Translator(to_lang="fr")try:with open('quote.txt', mode='r') as quote_file:# read the filequote = quote_file.read()# do the translationsquote_spanish = spanish_translate.translate(quote) quote_french = french_translate.translate(quote)# create the translated filestry:with open('quote-es.txt', mode='w') as quote_de: quote_de.write(quote_spanish)with open('quote-fr.txt', mode='w') as quote_fr: quote_fr.write(quote_french)except IOError as error: print('An error ocurred')raise (error)except FileNotFoundError as error: print('File not found')raise (error)复制代码
将会自动的生成这句引言的两个翻译文件。这看起来确实很棒!
内置文件操作模块
Python提供了一个叫做pathlib的内置模块作为标准库的一部分。它提供了各种方便表示文件系统路径的类,这些类具有适用于不同操作系统的语义。这个模块在Python3.4的时候被引入,它非常适用于处理有很多目录时。