在开发中经常要对数据进行持久化操作,实现数据持久化最直接的方式就是将数据保存到文件中。在 Python 中实现文件的读写操作非常简单,通过 Python 内置的函数,就可以获得操作文件的对象,从而对文件进行读写操作。
读取文件
首先,我们通过一个例子来看看如何使用Python内置的 open()
函数读取文件。在项目目录下创建一个文件,文件内容为字母表,文件名为 alphabet.txt
。
alphabet.txt内容
abcdefg
hijklmn
opq rst
uvw xyz
if __name__ == '__main__':
with open('alphabet.txt') as f:
contents = f.read()
print(contents)
运行结果如下,控制台打印出了文件的内容。
abcdefg
hijklmn
opq rst
uvw xyz
在这个程序中, with
关键字在不再需要访问文件后将文件关闭,当然,也可以调用 open()
和 close()
方法打开和关闭文件,但我比较推荐使用 with
关键字,因为 with
子句体结束后,文件会正确关闭,即便触发异常也可以。 open()
函数的作用是打开文件,它接收了一个要打开的文件名的参数,Python 在当前目录下查找指定的文件,如果查不到此文件,则会报错。在这个例子中,我们已经提前新建了文件,运行此程序时,Python 在当前执行的文件所在的目录下查找 alphabet.txt
,并返回了一个文件对象,将这个对象赋给 f
供我们使用。调用 read()
方法读取了这个文件的所有内容,并将其作为一个字符串赋值给 contents
变量,最后打印出这个变量的内容。
read(size)
函数有指定读取的内容长度参数 size
。当省略参数或参数为负数时,读取并返回整个文件的内容。其他情况下,读取并返回最多 size
个字符(文本模式)或 size
个字节(二进制模式)。
在 Python 中,open()
函数的定义一共有 7 个参数。
open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)
但常用的参数就两个,文件(file)和模式(mode)。参数 file
是文件名字符串,如果文件在其他位置,可以使用相对路径或者绝对路径表示文件位置。参数 mode
是包含描述文件使用方式字符的字符串。模式字符串有以下几种:
字符 | 描述 |
---|---|
r | 只读模式 (默认) |
w | 打开文件只用于写入,即原有内容删除,从开头开始写入 |
x | 新建文件用于写入 |
a | 如果文件存在,打开并追加内容到文件尾;如果文件不存在,创建新文件写入文件 |
b | 二进制模式 |
t | 文本模式 (默认) |
+ | 打开文件进行更新 (可读可写) |
在实际开发过程中,经常遇到要打开的文件不存在的情况,导致 Python 报错。为此,可以使用 Python 中的异常处理方法,使用 try-except
代码块处理异常。下面的例子演示了如何编写文件不存在时的异常处理。
if __name__ == '__main__':
try:
with open('a.txt') as f:
contents = f.read()
except FileNotFoundError:
print('The file does not exist.')
else:
print(contents)
因为当前执行文件目录下没有 a.txt
文件,所以会执行 FileNotFoundError
的异常处理,在控制台打印出 The file does not exist.
文本信息。 else
代码块放的是 try
代码块成功执行后需要继续执行的语句。
readline()
函数可以读取文件中单行内容。
if __name__ == '__main__':
try:
with open('alphabet.txt') as f:
line1 = f.readline()
line2 = f.readline()
except FileNotFoundError:
print('The file does not exist.')
else:
print(line2)
print(line1)
控制台输出如下
hijklmn
abcdefg
我们发现,在每打印一行后面还会再打印一行空行。这是因为在这个文件中,每行的行末都有一个看不见的换行符,并且调用 print()
函数时也会打印出一个换行符,因此才出现了这种情况。为此可以修改一下代码,删除这些多余的空白行。
if __name__ == '__main__':
try:
with open('alphabet.txt') as f:
line1 = f.readline()
line2 = f.readline()
except FileNotFoundError:
print('The file does not exist.')
else:
print(line2.rstrip())
print(line1.rstrip())
控制台输出如下
hijklmn
abcdefg
写入文件
在 Python 中写入文件的方法也很简单,只需要调用 write()
函数即可。
if __name__ == '__main__':
number = '1, 2, 3, 4, 5'
try:
with open('numbers.txt', 'w') as f:
f.write(number)
except FileNotFoundError:
print('The file does not exist.')
else:
print('writing succeed!')
执行完程序便可在目录下看到有新的文件 numbers.txt
。
使用JSON文件存储数据
在 Python 中,如果想要把嵌套列表、字典等复杂数据类型保存到文件中,使用上面所讲的方法非常麻烦。为此,我们可以使用 json
模块,把内容以字符串形式保存成 json 文件。
import json
if __name__ == '__main__':
dict = {
'name': 'Caizi',
'age': 18,
'friends': [
{'name': 'John', 'age': 19},
{'name': 'Mary', 'age': 20}
]
}
try:
with open('dict.json', 'w') as fs:
json.dump(dict, fs)
except IOError as e:
print(e)
print('success!')
其中, dump()
方法接收两个参数,第一个参数是要存储的数据,第二个参数是用于存储数据的文件对象。运行后得到的 dict.json
文件。
{"name": "Caizi", "age": 18, "friends": [{"name": "John", "age": 19}, {"name": "Mary", "age": 20}]}
要读取 json 文件,使用 load()
方法即可。
import json
if __name__ == '__main__':
try:
with open('dict.json') as fs:
dict = json.load(fs)
except IOError as e:
print(e)
print(dict)
执行后获取到了 dict.json
文件内容。
{'name': 'Caizi', 'age': 18, 'friends': [{'name': 'John', 'age': 19}, {'name': 'Mary', 'age': 20}]}
当然,操作文件对象还有一些方法,但平时不常使用,所以在此不提及这些方法。