很多时候,程序要把信息存储在列表和字典等数据结构中。一种简单的方式是使用json模块来存储数据。
json模块能够将简单的Python数据结构存储到文件中,并在程序运行时加载文件中的数据。还可以使用json在Python程序之间分享数据。更重要的是,JSON数据格式并非Python专用的,能够将以JSON格式存储的数据与使用其他编程语言的人分享。
JSON(JavaScript Object Notion)格式最初是为JavaScript开发的,随后被包括Python在内的多种语言采用,成了一种常见的格式。
1、使用json.dump()和json.load()
使用json.dump()来存储数据,使用json.load()来加载数据。
函数json,dump有两个参数:要存储的数据以及可用的文件对象。
python">import json
numbers =[ 5,4,8,6,2]
filename = 'numbers.json'
with open(filename,'w') as f:json.dump(numbers,f)
首先导入json模块,创建数据,指定文件名(使用后缀.json来表明文件存储的数据格式为JSON格式)。以写模式打开文件,使用json.dump()存储数据。
numbers.json:
python">[5, 4, 8, 6, 2]
接着使用json.load()将数据加载:
python">import jsonfilename = 'numbers.json'
with open(filename) as f:numbers = json.load(f)
print(numbers)
python">[5, 4, 8, 6, 2]
2、保存和加载用户生成的数据
还可以使用json保存用户生成的数据,防止程序运行结束时用户信息丢失。
python">import jsonname = input('Please input your name: ')
filename = 'names.json'
with open(filename,'w') as f:json.dump(name, f)print("Hello, " + name)
运行一次:
python">Please input your name: Liang
Hello, Liang
接着将文件中存储的数据加载:
python">import jsonfilename = 'names.json'
with open(filename) as f:name = json.load(f)print("Hello again, " + name)
python">Hello again, Liang
可以将两个文件合并为一个文件,使用try-except:
save_name.py
python">import jsonfilename = 'names.json'
try:with open(filename) as f:name = json.load(f)
except FileNotFoundError:name = input('Please input your name: ')with open(filename,'w') as f:json.dump(name, f)print("Hello, " + name)
else:print("Hello again, " + name)
如果文件存在,将文件中的数据加载并执行else中的代码块;否则,执行except中的代码块,提示用户输入姓名并使用json.dump()存储数据到文件。
3、重构
重构是指这样的过程:代码可以正常运行但可以进一步改进(如将代码划分为一系列完成具体工作的函数)。重构让代码更加清晰、更易于理解、更容易扩展。
例如,重构上述的save_name.py,划分为多个具体的函数。
save_name.py:
python">import jsondef greet():"""问候用户"""filename = 'names.json'try:with open(filename) as f:name = json.load(f)except FileNotFoundError:name = input('Please input your name: ')with open(filename,'w') as f:json.dump(name, f)print("Hello, " + name)else:print("Hello again, " + name)greet()
定义了一个函数,但该函数执行的内容太多了,还可以进一步细分:
python">import jsondef get_name():"""获取用户名"""filename = 'names.json'try:with open(filename) as f:name = json.load(f)except FileNotFoundError:return Noneelse:return namedef greet():"""问候用户"""name = get_name()if name:print("Hello again, " + name)else:name = input('Please input your name: ')filename = 'names.json'with open(filename, 'w') as f:json.dump(name, f)print("Hello, " + name)greet()
使用了两个函数,但第二个函数还可以进一步划分:
python">import jsondef get_name():"""获取用户名"""filename = 'names.json'try:with open(filename) as f:name = json.load(f)except FileNotFoundError:return Noneelse:return namedef input_name():"""用户输入名字"""name = input('Please input your name: ')filename = 'names.json'with open(filename, 'w') as f:json.dump(name, f)return namedef greet():"""问候用户"""name = get_name()if name:print("Hello again, " + name)else:name = input_name()print("Hello, " + name)greet()
在最终版本中,每个函数都只执行一项具体而清晰的任务。greet()要么找到文件再次欢迎,要么没找到文件提示用户输入新建文件首次欢迎。get_name()负责获取文件中的姓名,没有该文件则返回None。input_name()负责在没找到文件时,提示用户输入姓名,并创建文件,返回姓名。
这种清晰而明确的划分对于编写易于阅读和维护的代码极其重要。