6.1 目录和文件是什么?
对于当今的少年儿童来说,他们比较习惯的是手机和平板电脑,他们可能还没有接触普通电脑,所以有必要解释一下目录和文件的概念。
电脑、手机和平板电脑都有存储,电脑上是硬盘,手机和平板上是其他存储介质,但都是按照目录和文件的方式存储数据的。
硬盘上分多个目录,用来保存不用类型的文件,一个目录下可以再继续分目录,这称为子目录,层层分下去可以分很多层,每层目录都可以保存文件,类似下面的结构:
\目录1
\目录1\目录11
\目录1\目录11\文件11-1.py
\目录2
\目录2\文件2-1.dat
文件比较容易理解,比如手机上我们安装一个APP,一般从应用市场上安装,背后的原理是应用市场会从网上下载一个安装文件,然后运行这个安装文件进行安装,这个安装文件就是文件的一种。
我们在前面章节写的程序代码可以保存到一个文件里,这个程序文件也是文件的一种。
还有一种比较常见的文件是数据文件,也就是可以保存一些数据在里面,例如对于游戏软件,在运行过程中会产生很多数据,例如打到哪一关了,装备情况怎么样,等等。这些数据文件可以保存到硬盘里,下次再运行游戏软件时可以再次读取,这样我们可以接着上次暂停的地方继续玩下去。
在本套教程里我们常用到的有两种,一种是 Python 程序文件,里面是程序代码,用 文件名.py 这样格式存储;另一种是数据文件,里面保存程序用到的一些数据,用 文件名.dat 这样格式存储。.py 和 .dat 叫作文件扩展名,用于区分文件类型的。
6.2 读文件
Python 提供了内嵌函数可以用来操作文件,看一下这个示例:
1 | file = open("test1.dat", "r") |
这段代码运行时需要在程序文件目录下有个 test1.dat 文件,可以找个编辑器软件随便输点内容保存成这个文件名字就可以。
open(“test1.dat”, “r”) 就是使用内嵌函数 open 打开一个文件,调用这个函数有两个参数,一个是文件名称,准确说是文件目录,也就是保存在某个目录下的一个文件路径。我们在文件名字前不加任何目录时表示在程序运行当前目录;第二个参数是文件访问模式,”r” 表示用只读模式去访问,还有 “w” 模式是写模式访问。
这个函数在成功打开一个文件后会返回一个文件对象,我们用 file = open(“test1.dat”, “r”) 把这个文件对象赋值给 file 变量,下面就可以通过 file 变量就代表这个文件对象了,可以用它访问文件内容了。
我们在前面对象那一章节解释过,对象有属性,也有操作方法,我们就是用 file 这个对象的 read 方法读取文件中的所有内容,并且赋值给变量 fileContent,然后用 file 对象的 close 方法关闭文件,最后打印出 fileContent。
(注释:打开文件用完后及时关闭,这个是比较好的编程习惯,我们打开的文件实际上是占用了一个资源,用完后需要尽快释放以便给其他程序使用,因为系统的可用资源数量是有限的,比如一个系统可能同时只能打开1000个文件,如果我们每次打开都没关闭,运行1000次后就占用了所有可用的文件资源数,再运行就报错了,也就意味着程序不能再用了。)
6.3 写文件
写文件的用法跟读文件类似,也是先打开文件,然后写内容到文件,然后关闭文件,看一下这段代码:
1 | file = open("test1.dat", "w") |
第一行是打开一个文件,第一个参数是文件名,第二个是打开模式,这里是 “w”,表示写模式。
第二行是定义了一个变量 fileContent,保存了一个字符串。
第三行是用文件对象的 write 方法写字符串内容到文件。
第四行是关闭文件对象,也是类似道理,打开文件用完后记得及时关闭,这样可以及时释放占用的资源。
6.4 保存对象到文件和加载文件中的对象
这一节要用到一个新概念叫“模块”,模块在下一章会详细讲解,这里只是需要用到,先简单解释一下。
模块可以理解为把一组相关的函数放在一起,起个分类名字,然后通过这个分类名字加函数名字来使用这些函数。
这里我们要用到 pickle 这个模块,它是用于把对象保存到文件以及从文件加载出对象,通过它我们可以很方便地把数据保存到文件里,也能把数据从文件中加载出来。
看一下这段代码:
1 | import pickle |
import pickle 这行代码就是引入 pickle 模块,import 是指令,pickle 是模块名字。
file = open(“test1.dat”, “wb”) 是打开一个文件,用 “w” 写模式,但还多了个 “b”,”b” 表示以二进制(binary)的方式读写,以前不加 “b” 的时候是以文本方式读写的,也就是这个文件可以用普通文本编辑器打开查看,如果加了 “b” 就只能通过程序读写了,pickle 模块要求是以二进制方式读写。
dataList = [10, 20, 30] 是定义一个列表,我们打算把这个列表对象保存到文件中。
pickle.dump(dataList, file) 是把列表对象 dataList 保存到文件对象 file 中。
file.close() 是关闭文件,要记住这个良好的习惯,打开文件用完后及时关闭。
运行这段代码就能成功把数据保存到文件中了,怎么检验有没有保存成功呢?要用从文件加载对象的方法,看一下这段代码:
1 | import pickle |
第一行是引入 pickle 模块。
第二行 file = open(“test1.dat”, “rb”) 是打开文件,用 “rb” 的模式,表示读取二进制模式。
第三行 dataList1 = pickle.load(file) 就是从打开的文件对象中加载数据对象,并把加载结果赋值给 dataList1 变量。
第四行 file.close() 是关闭文件对象,好习惯。
第五行 print(dataList1) 是打印加载出来的数据。
运行上面这段代码会发现从文件加载出来的数据跟我们保存的数据是一致的。
6.5 实践练习时间
过去章节我们学习了文件读写操作功能,下面通过几个实践练习来加深理解。
练习1:
先用一个文本编辑器(例如 Windows 里的记事本)编辑一个文件,随便敲入一些文字,保存到你写程序的目录下,起个文件名字,例如 test1.txt,然后写个程序读取这个文件的内容,并打印出来。
练习2:
写个程序,定义一个字符串变量,随便敲入一些字符作为它的值,然后用写的方式打开刚才练习1里那个文件,把这个字符串变量的值写入文件,运行程序后再用文本编辑器打开看看文件内容。
练习3:
写个程序,定义一个列表,保存这几个姓名 “John”、”Mary”、“Alice”,然后使用 pickle 模块把这个列表保存到一个文件里。然后再通过 pickle 模块从这个文件加载列表对象到另一个变量名,打印这个变量。