python对json文件封装处理,增删改查操作

python对json文件封装处理

为了解决json文件处理需求,更方便的读写json文件,对其进行增删改查操作,利用json库及eval,
exec函数特性,封装成工具类,记录个人学习心得。

  1. demo.json
{
    "name": "BeJson",
    "url": "http://www.bejson.com",
    "page": 88,
    "isNonProfit": true,
    "address": {
        "street": "科技园路.",
        "city": "江苏苏州",
        "country": "中国"
    },
    "links": [
        {
            "name": "Google",
            "url": "http://www.google.com"
        },
        {
            "name": "Baidu",
            "url": "http://www.baidu.com"
        },
        {
            "name": "SoSo",
            "url": "http://www.SoSo.com"
        }
    ]
}
  1. JsonTool.py
import json
from typing import List, Dict, Any


class JsonTool:
    """ json文件 封装工具"""

    def __init__(self):
        self.fp = None
        self.load_dict = None

    def _key_join(self, key_list: List) -> str:
        """ key数据拼接 """
        temp = "self.load_dict"
        for _, key in enumerate(key_list):
            if ":" in key:
                kv = key.split(":")[0]
                index = int(key.split(":")[1])
                temp += f'[{index}]["{kv}"]'
            else:
                temp += f'["{key}"]'
        return temp

    def read_file(self, file=None) -> Dict:
        """
        读取json文件,返回 python字典数据
        :return:
        """
        self.fp = file
        if not self.fp:
            raise Exception("未指定文件路径")

        try:
            with open(self.fp, 'r', encoding='utf-8') as load_f:
                self.load_dict = json.load(load_f)
                # format_load_dict = json.dumps(self.load_dict, indent=4, separators=(',', ':')
                #                               ensure_ascii=False)  # ,sort_keys=True
                # print('read_file:\n', format_load_dict)
            return self.load_dict
        except ValueError as err:
            print(f"{self.fp}json文件读取失败或格式有误:{err}")

    def write_file(self, file=None) -> None:
        """
        json文件变更操作后,回写入文件
        :return:
        """
        if not file:
            file = self.fp
        with open(file, 'w', encoding='utf-8') as write_f:
            json.dump(self.load_dict, write_f, indent=4,
                      ensure_ascii=False)   # , separators=(',', ':')

    def validateJSON(self, path=None) -> bool:
        """
        校验json文件是否正确
        :return: True/False
        """
        try:
            with open(path, 'r', encoding='utf-8') as load_f:
                self.load_dict = json.load(load_f)
        except ValueError as err:
            print(f"{self.fp}json文件读取失败或格式有误:{err}")
            return False
        return True

    def get_values(self, key_list: List) -> List:
        """
        从嵌套的json数据中获取指定key的所有值.
        example: get_values(["links", "url"])
        :key_list: 一级一级嵌套的List
        :return: json-value
        """
        temp = self._key_join(key_list[:-1])
        dataList = [item.get(key_list[-1]) for item in eval(temp)]
        return dataList

    def get_value(self, key_list: List) -> Any:
        """
        从嵌套的json数据中获取对应一个key的值
        example: get_value(["page"]), get_value(["links", "name:0"])
        :key_list: 一级一级嵌套的List
        :return: json-value
        """
        # print(f"{self._key_join(key_list[-1])=}")
        # print(f"{eval(self._key_join(key_list[-1]))=}")
        if len(key_list) > 1 and len(eval(self._key_join(key_list[:-1]))) >= 2 and ":" not in key_list[-1]:
            raise Exception("指定key存在多个,请指定下标")
        temp = self._key_join(key_list)
        return eval(temp)

    def set_value(self, key_list: List, value: Any = "None") -> None:
        """
        从嵌套的json数据中设置或者添加值
        example: set_value(["address", "house"], "大别野")
        :key_list: 一级一级嵌套的List
        :return:
        """
        temp = self._key_join(key_list)
        if isinstance(value, str):
            result = temp + f'="{value}"'  # eval函数不能执行赋值操作, 使用另一个强大的函数exec
        elif isinstance(value, int) or isinstance(value, bool):
            result = temp + f'={value}'
        elif isinstance(value, list) or isinstance(value, tuple):
            result = temp + f'={value}'
        exec(result)

    def remove_key(self, key_list):
        """ 移除 json指定字段数据 """
        temp = "del " + self._key_join(key_list)
        exec(temp)


if __name__ == '__main__':
    config = JsonTool()
    if config.validateJSON("./demo.json"):
        config.read_file("./demo.json")
    print(f"config.load_dict_0: {config.load_dict}")
    # config.get_value(["links", "name"])   # X
    n_v1 = config.get_value(["links", "name:0"])
    n_v2 = config.get_value(["links", "name:1"])
    n_v3 = config.get_value(["page"])
    n_v4 = config.get_value(["isNonProfit"])
    print(f"n_v1: {n_v1}, n_v2: {n_v2}, n_v3: {n_v3}, n_v4: {n_v4}")
    config.set_value(["links", "name:2"], "Souhu")
    config.set_value(["isNonProfit"], False)
    config.set_value(["page"], 90)
    print(f"config.load_dict_1: {config.load_dict}")
    link = [
        {
            "name": "Google",
            "url": "http://www.google.com"
        },
        {
            "name": "Baidu",
            "url": "http://www.baidu.com"
        }
    ]
    config.set_value(["links"], link)
    config.set_value(["address", "house"], "大别野")
    config.remove_key(["address", "street"])  # 科技园路.
    print(f"config.load_dict_2: {config.load_dict}")
    config.write_file("./res.json")
    n_v5 = config.get_values(["links", "url"])
    print(f"n_v4: {n_v5}")

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值