30天学习Python????‍????第十八天——文件I/O

文件操作概述

今天我将探索怎样使用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的时候被引入,它非常适用于处理有很多目录时。