Bootstrap

Python中存储数据——json模块

        很多时候,程序要把信息存储在列表和字典等数据结构中。一种简单的方式是使用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有两个参数:要存储的数据以及可用的文件对象。

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:

[5, 4, 8, 6, 2]

        接着使用json.load()将数据加载:

import json

filename = 'numbers.json'
with open(filename) as f:
    numbers = json.load(f)
print(numbers)
[5, 4, 8, 6, 2]

2、保存和加载用户生成的数据

        还可以使用json保存用户生成的数据,防止程序运行结束时用户信息丢失。

import json

name = input('Please input your name: ')
filename = 'names.json'
with open(filename,'w') as f:
    json.dump(name, f)
    print("Hello, " + name)

运行一次:

Please input your name: Liang
Hello, Liang

         接着将文件中存储的数据加载:

import json

filename = 'names.json'
with open(filename) as f:
    name = json.load(f)
    print("Hello again, " + name)
Hello again, Liang

        可以将两个文件合并为一个文件,使用try-except:

save_name.py

import json

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)

如果文件存在,将文件中的数据加载并执行else中的代码块;否则,执行except中的代码块,提示用户输入姓名并使用json.dump()存储数据到文件。

3、重构

        重构是指这样的过程:代码可以正常运行但可以进一步改进(如将代码划分为一系列完成具体工作的函数)。重构让代码更加清晰、更易于理解、更容易扩展。

        例如,重构上述的save_name.py,划分为多个具体的函数。

save_name.py:

import json

def 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()

定义了一个函数,但该函数执行的内容太多了,还可以进一步细分:

import json

def get_name():
    """获取用户名"""
    filename = 'names.json'
    try:
        with open(filename) as f:
            name = json.load(f)
    except FileNotFoundError:
        return None
    else:
        return name
    
def 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()

使用了两个函数,但第二个函数还可以进一步划分:

import json

def get_name():
    """获取用户名"""
    filename = 'names.json'
    try:
        with open(filename) as f:
            name = json.load(f)
    except FileNotFoundError:
        return None
    else:
        return name


def input_name():
    """用户输入名字"""
    name = input('Please input your name: ')
    filename = 'names.json'
    with open(filename, 'w') as f:
        json.dump(name, f)
    return name

def greet():
    """问候用户"""
    name = get_name()
    if name:
        print("Hello again, " + name)
    else:
        name = input_name()
        print("Hello, " + name)

greet()

        在最终版本中,每个函数都只执行一项具体而清晰的任务。greet()要么找到文件再次欢迎,要么没找到文件提示用户输入新建文件首次欢迎。get_name()负责获取文件中的姓名,没有该文件则返回None。input_name()负责在没找到文件时,提示用户输入姓名,并创建文件,返回姓名。        

        这种清晰而明确的划分对于编写易于阅读和维护的代码极其重要。

;