很多程序要求用户输入某种信息,如让用户存储游戏首选项或提供可视化的数据。不管你专注的是什么,程序都把用户提供的信息存储在列表和字典等数据结构中。用户关闭程序时,你几乎总需要保存他们提供的信息;一种简单的方式是使用json存储数据。
模块json让你能够将简单的python数据结构转储到文件中,并在程序再次运行时加在该文件中的数据。你还可以使用json在python程序之间分享数据。更重要的是,json数据格式并非python专用的,这让你能将以json格式存储的数据与其他人分享。
JSON(JavaScript Object Nation)最初是为javascript开发的,但随后成了一种常见的格式,被包括python在内的众多语言中采用。
一、使用json.dump()和json.load()
json.dump()存储数字,json.load()将数字读取到内存中
函数json.dump()接受两个实参:要存储的数据和可用于存储数据的文件对象。下面演示如何使用json.dump来存储数字列表:
number_write.py
import json
number = [2,3,5,7,11,13]
filename = 'number.json'
with open(filename,'w') as f_obj:
json.dump(number, f_obj)
我们先导入模块json,在创建一个数字列表。
filename = 'number.json':指定了要将该数字列表存储到其中的文件的名称。通常使用文件扩展名.json来指出文件存储的数据JSON格式。
with open(filename,'w') as f_obj:以写模式打开文件,让json能够将数据写入其中。
json.dump(number, f_obj):使用函数json.dump将数字列表存储到文件number.json中。
这个程序没有输出
下面在编写一个程序,使用json.load()将这个列表读取到内存中:
number_reader.py
import json
filename = 'number.json'
with open(filename) as f_obj:
numbers = json.load(f_obj)
print(numbers)
filename = 'number.json':确保读入的是前面写入的文件
with open(filename) as f_obj::读取方式打开文件,默认不指定为读取
numbers = json.load(f_obj):使用函数json.load加在存储在numbers.json中的信息,并将其存储到变量numbers中。
二、保存和读取用户生成的数据
对于用户生成的数据,使用json保存他们大有裨益,因为如果不以某种形式进行存储,等城固县结束之后用户信息将丢失。
例:用户首次运行时被提示输入自己的名字,这样再次运行程序是就记住他了。
remember_me.py
import json
username = input("what is your name?")
filename = 'username.json'
with open(filename,'w') as f_obj:
json.dump(username,f_obj)
print("we'll remember you when you come back, " +username + "!")
运行结果如下:
现在在编写一个程序,向其名字被存储的用户发出问候:
greet_user.py
import json
filename = 'username.json'
with open(filename) as f_obj:
username = json.load(f_obj)
print("welcome back, " + username + "!")
我们需要将两个程序合并到一个程序(remember_me.py)中。程序运行期间,我们将尝试从文件username.json中获取用户名,因此我们首先编写一个尝试恢复用户名的try代码块。如果文件不存在,我们就在except代码块中提示用户输入用户名,并将其存储在username.json中,一边程序能够获取它。
import json
#如果以前存储了用户名,就加载它
#否则,就提示用户输入用户名并存储它
filename = 'username.json'
try :
1 with open(filename) as f_obj:
2 username = json.load(f_obj)
3except FileNotFoundError:
4 username = input('what is your name?')
5 with open(filename,'w') as f_obj:
json.dump(username, f_obj)
print("we'll remember you when you come back, " + username + "!")
else:
print("welcome back, " + username + "!")
1处尝试打开文件username.json,如果这个文件存在,就将其中的用户名读取到内存中(见2),在执行else代码块,即打印一条欢迎用户回来的消息。用户首次运行·这个程序时,文件username.json不存在将引发FileNotFoundError异常(见3),因此python将会自行except代码块:提示用户输入用户名(见4),在使用json.dump()存储用户名,并打印一句问候语(见5)
三、重构
重构:代码能够正确运行,但可作进一步的改进——将代码划分成一系列完成具体工作的函数。这样的过程称为重构,重构让代码更清晰、更易于理解、更易于扩展
要重构remember_me.py,可将其中大部分逻辑放到一个或多个函数中。remeber_me.py的重点是问候用户,因此我们将其所有代码都放到一个名为greet_user()函数中:
remember.py
import json
def greet_user():
"""问候用户,并指出其名字"""
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
username = input('what is your name?')
with open(filename,'w') as f_obj:
json.dump(username, f_obj)
print("we'll remember you when you come back, " + username + "!")
else:
print("welcome back, " + username + "!")
greet_user()
但是函数greet_user()所做的不仅仅是问候用户,还在存储了用户名的时候获取它,而在没有存储用户名时提示用户输入一个。下面重构greet_user(),让它不执行那么多任务。首先将获取存储用户名的代码移到另一个函数中:
import json
def get_stored_username():
"""如果存储了用户名,就获取它"""
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
return None
else:
return username
def greet_user():
"""问候用户并指出其名字"""
username = get_stored_username()
if username :
print("welcome back, " + username + "!")
else:
username = input("what's your name?")
filename = 'username.json'
with open(filename,"w") as f_obj:
json.dump(username,f_obj)
print("we'll remember you when you come back, " + username + "!")
greet_user()
新增的函数get_stored_username()目标明确,如果存储了用户名,这个函数就获取它并返回;如果文件username.json不存在,这个函数就返回None。如果成功获取用户名就打印一条欢迎用户回来的消息,否则就提示用户输入用户名。
我们还需将greet_user()中的另一个代码块提取出来:将没有存储用户名时提示用户输入的代码放在一个独立的函数中:
import json
def get_stored_username():
#如果存储了用户名,就获取它
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except FileNotFoundError:
return None
else:
return username
def get_new_username():
"""提示用户输入用户名"""
username = input("what's your name?")
filename = 'username.json'
with open(filename,'w') as f_obj:
json.dump(username, f_obj)
return username
def greet_user():
"""问候用户,并指出其名字"""
username = get_stored_username()
if username :
print("welcome back, " + username + "!")
else:
username = get_new_username()
print("we'll remember you when you come back, " + username + "!")
greet_user()