如何永久的保存输入的信息,并在合适的时机输出出来 —— 文件的输入和输出。

这节木辛老师将带领大家一起揭开 Python中文件操作的神秘面纱。

之前的课程已经讲过程序包含3个主要方面:输入、输出和处理。

到目前为止,主要学习过得输入是来自用户的:键盘输入和鼠标输入;输出主要是在屏幕上打印信息、播放音乐音效。

然而这些操作都是瞬间的,当程序关闭以后,对应数据也就烟消云散了。

文件是什么

在开始学习Python读写文件之前,我们先来看看文件是什么。

咱们讲过,计算机按照二进制格式存储信息,二进制只使用1和0。每个1或者0称为一个bit,8位一组称为一个字节。

文件是有名字的字节的集合,存储在硬盘,U盘,云盘上等介质上的。

一个文件可以是文本文件、图片文件、音乐文件,也可以是计算机程序、手机号码、QQ号码等内容。

计算机硬盘上的所有内容都是以文件的形式存放的。程序就是有一个或者多个文件组成。

咱们的计算机的操作系统同样也是有很多文件的支持,才能运起来的。

文件包含如下属性:名字

类型,比如:图片、音乐、文档

存放位置

大小

文件是有名字的

在大多数文件系统中,文件名由两个部分组成:用来指明文件类型的扩展名部分,比如:.mp3、.txt 、.wma

另一部分则是根据自己的喜好,或者实际需求命名的文件的一个描述木系老师说一说

有一点很重要,咱们可以根据自己的喜好命名文件,还可以使用任意的扩展名。

比如:木辛老师就经常将重要的数据文件命名为.dat文件。这么做的目的只是提醒木辛老师,这是一个很重要的数据,但是有一个比较麻烦的后果就是:计算机被搞的云里雾里,不知道这个是什么文件,每次打开的时候都要询问使用什么程序读取。

所以啊,建议大家还是使用一个和文件类型一直的扩展名字吧。

文件存放在哪里

到目前为止,我们一直处理与程序存储在同一个目录下的文件。根本不需要考虑如何查找。

就像你写字桌上的电脑或者手机,如果你哪天随手将手机放到了其他地方,那要是找起来就麻烦多了!

每个文件都要存储在某一个地方,所以除了文件名称以外,还有需要记录他的位置。

硬盘和其他存储媒介都是以文件夹为一个组织单元的。文件夹或者目录表示的是同一个东西,只是名字不同罢了。

他们都是一种组织文件的方法。文件夹或者目录组织和关联的方式称为文件夹结构或者目录结构。木辛博士说

位于其他文件夹中的文件夹称为子文件夹(subfolder)。如果使用属于“目录”来描述,可以把它们称为子目录(subdirectory)。

通过程序访问文件的时候,需要提供一个完整的地址,比如:

/PycharmProjects/PygameDemo/thumbnail.jpeg

这个称为路径,描述了文件在目录结构中的位置。

这个特定的路径表达的意思是:从根目录(/)开始;(这里的根目录是类Linux文件系统的称呼,请关注木辛老师后续的Linux课程,获取更多知识吧)

进入名为PycharmProjects的目录

在PycharmProjects目录中,进入下一级PygameDemo的子目录

在PygameDemo子目录中有一个图片文件:thumbnail.jpeg

这样,计算机就可以知道我们的图片文件thumbnail.jpeg了。同理,可以找到计算机上的任何文件。

程序也是利用这种方法查找和打开文件的

thumbnail_file = "/PycharmProjects/PygameDemo/thumbnail.jpeg"

不知道大家还记得咱们之前的课程里,有使用过加载文件的代码

不过在这篇课程里,咱们写的路径稍微不同:

thumbnail = pygame.image.load("./thumbnail.jpeg”)

这里的路径并不是完整的文件路径,而是叫相对路径,因为./表示的是程序同一个目录下;

也就是说这个图片需要程序在同一个目录下寻找,而不需要去根目录然后各级子目录寻找了。

嗯嗯,目录的基础知识讲的差不多了,小朋友们如果还有任何疑问,可以随时私信木辛老师哟!

打开文件

在打开文件之前,咱们需要明确对文件做什么:如果需要使用这个文件作为输入(只查看文件内容,不做任何改变)就是要打开文件完成读;

如果要创建一个全新的文件或者用某个全新的文件替换现有的文件,就要打开文件完成写;

如果要为一个现有的文件增加内容,就是要打开文件完成追加。

Python中很多东西都是对象,文件也不例外;打开一个文件,就是要建立一个文件对象。

建立文件对象需要使用open()函数,并提供文件名:

my_file = open('./my_file.txt', 'r')

文件名是一个字符串,所以两边需要加引号。“r”表示我们要打开文件来完成读操作。

一定要分清楚文件对象和文件名之间的区别哟!

我们在程序中要用到的文件对象来访问文件,而文件名是磁盘上的文件的名字。

文件已经打开了,然我们接着进行下一个操作吧

读文件

在使用open()函数打开文件并创建文件对象之后,我们就需要进行下一步操作了:读文件。

但是,大家有没有想过一个问题:如果这个文件不存在会怎么样呀:

Python如何打开文件

嗯嗯,Python会很友好的提示我们:这个文件或者目录不存在。

就像咱们之前的课程里反复强调的一样:不能操作不存在的东西!

一次读取多行

打卡文件之后呢,咱们就可以使用Python提供的另外一些内置的功能了,比如说:要从一个文件读取所有的行:

lines = my_file.readlines()

这条语句会读取整个文件,并建立一个列表,每一个文本行将作为列表中的一个项。我们写个小例子看看吧:

文本文件内容

文本文件的读

嗯,输出的结果和我们预期的是完全一样滴。好开心呀!

一旦把文件读取为程序中的一个字符串列表,接下来就可以任意处理它了。

这个列表和Python的其他列表是一样的。所以可以循环处理、排序、追加元素、删除元素等等。

一次读取一行

readlines()方法会读取文件的所有行,直到文件的末尾。如果只是想每次读取一行呢?

Python给我们提供了readline()方法:

first_line = my_file.readline()

这只会读取文件的第一行。如果再调用一次这个语句,Python会读取第二行;以此类推。

所以,readline()这个函数每次读取一行,它不会将结果放入一个列表。

每次使用只是得到一个字符串。直到读到文件的末尾位置。

小朋友们可能要问了,那么我读取了10行之后,再想重新读取第一行咋办呀?

Python已经提前帮我们想到了,它提供了一个函数seek(),这个函数的作用就是:通知Python退回到指定的那一行,然后从那一行开始读取数据。

具体是哪一行,只需要在seek()函数传入整型的数字就可以了,比如我们想要退回到第一行

seek(0)

这样,就可以从文本文件的第一行重新开始读取数据了。

文本文件和二进制文件

到目前为止,我们都假设的是在处理一个文本文件,认为在文件中的内容都是文本。

但是,请小朋友们注意:文件能够存储任何内容,文本文件只是文件的其中一种而已。很多人会把所有其他类型的文件都统称为二进制文件(binary file)。

我们目前所能接触到的文件主要包含两个类型文本文件:这些文件包含了文本,包括字母、数字、标点符号和一些特殊字符,比如换行符、制表符等

二进制文件:这些文件不包含文本,可能包含音乐、图片或者其他数据。不过由于不包含文文本,所以这些文件中也没有行,因为根本不存在换行符。

所以啊,在读取二进制文件的时候,是不能使用readlines()和readline()函数的。

Python为了解决这个问题提供了很多相应的函数。大家是否还记得我们之前通过Pygame加载音效和音乐的时候使用的方法呢?

pygame.mixer.music.load(“bg_music.mp3”)

这也是一种读取二进制文件的方法。

当然了,这个函数是pygame的一个方法,是建立在Python自己的二进制文件读取方法之上的:

my_music_file = open(‘bg_music.mpe’,’rb’)

就像上边这样,Python就可以轻松的读取一个二进制文件了:只需要在使用open函数的时候,传入第二个数“rb”即可,“rb”代表就是 read binary的意思了。

二进制文件多种多样,我们在这里就不深入的展开来讲了,有兴趣的小朋友们可以私信木辛老师,获取更多关于操作系统,文件系统的知识哟!

写文件

如果想更持久的保存程序中的信息,最好的办法就是讲信息保存在硬盘上,这样一来,即使程序已经关闭了,但是你的数据仍然能保存下来。其实咱们在最开始的课程里就讲过了:

咱们通过IDLE新建文件,编写完代码后,点击保存。其实就是讲Python文件保存到了硬盘上了。

写文件的方法有两种:写 : 表示开始一个新文件,或者覆盖现有的文件

追加 :表示增加到现有文件中,保留原来已经存在的内容

这两种方式的不同就在于,打开文件写的时候,传入的数写:使用“w”参数

追加:使用“a”

就是这么简单,大家掌握了吗?

好了,今天的课程咱就先讲到这里吧,小朋友们学会了如何操作文件的读写,以后的程序就可以好好的保存起来了。