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}")

由于这是一个比较复杂的代码需求,我无法在这里给出完整的代码。但我可以给您提供一个大致的代码框架,供您参考: 1. 数据库设计 - 图书表(book):id、书名、作者、出版社、出版时间、价格等字段; - 用户表(user):id、用户名、密码、角色等字段; - 借阅记录表(borrowing):id、用户id、图书id、借阅时间、归还时间等字段。 2. 三层Web项目架构 - 数据访问层(Data Access Layer,DAL):负责与数据库进行交互,封装数据操作的方法; - 业务逻辑层(Business Logic Layer,BLL):负责处理业务逻辑,调用DAL层的方法进行数据增删改查操作; - 表现层(Presentation Layer,PL):负责与用户进行交互,展现数据,接受用户的请求并传递给BLL层进行处理。 3. 后端代码实现 DAL层 ```python import mysql.connector class BookDAL: def __init__(self, config): self.conn = mysql.connector.connect(**config) self.cursor = self.conn.cursor() def __del__(self): self.conn.close() # 获取所有图书 def get_all_books(self): sql = "SELECT * FROM book" self.cursor.execute(sql) return self.cursor.fetchall() # 添加图书 def add_book(self, book): sql = "INSERT INTO book (name, author, publisher, publish_date, price) VALUES(%s, %s, %s, %s, %s)" self.cursor.execute(sql, (book['name'], book['author'], book['publisher'], book['publish_date'], book['price'])) self.conn.commit() return self.cursor.lastrowid # 修改图书信息 def update_book(self, book): sql = "UPDATE book SET name=%s, author=%s, publisher=%s, publish_date=%s, price=%s WHERE id=%s" self.cursor.execute(sql, (book['name'], book['author'], book['publisher'], book['publish_date'], book['price'], book['id'])) self.conn.commit() return self.cursor.rowcount # 删除图书 def delete_book(self, book_id): sql = "DELETE FROM book WHERE id=%s" self.cursor.execute(sql, (book_id,)) self.conn.commit() return self.cursor.rowcount class UserDAL: def __init__(self, config): self.conn = mysql.connector.connect(**config) self.cursor = self.conn.cursor() def __del__(self): self.conn.close() # 获取所有用户 def get_all_users(self): sql = "SELECT * FROM user" self.cursor.execute(sql) return self.cursor.fetchall() # 添加用户 def add_user(self, user): sql = "INSERT INTO user (username, password, role) VALUES(%s, %s, %s)" self.cursor.execute(sql, (user['username'], user['password'], user['role'])) self.conn.commit() return self.cursor.lastrowid # 修改用户信息 def update_user(self, user): sql = "UPDATE user SET username=%s, password=%s, role=%s WHERE id=%s" self.cursor.execute(sql, (user['username'], user['password'], user['role'], user['id'])) self.conn.commit() return self.cursor.rowcount # 删除用户 def delete_user(self, user_id): sql = "DELETE FROM user WHERE id=%s" self.cursor.execute(sql, (user_id,)) self.conn.commit() return self.cursor.rowcount class BorrowingDAL: def __init__(self, config): self.conn = mysql.connector.connect(**config) self.cursor = self.conn.cursor() def __del__(self): self.conn.close() # 获取所有借阅记录 def get_all_borrowings(self): sql = "SELECT * FROM borrowing" self.cursor.execute(sql) return self.cursor.fetchall() # 添加借阅记录 def add_borrowing(self, borrowing): sql = "INSERT INTO borrowing (user_id, book_id, borrowing_date, return_date) VALUES(%s, %s, %s, %s)" self.cursor.execute(sql, (borrowing['user_id'], borrowing['book_id'], borrowing['borrowing_date'], borrowing['return_date'])) self.conn.commit() return self.cursor.lastrowid # 修改借阅记录信息 def update_borrowing(self, borrowing): sql = "UPDATE borrowing SET user_id=%s, book_id=%s, borrowing_date=%s, return_date=%s WHERE id=%s" self.cursor.execute(sql, (borrowing['user_id'], borrowing['book_id'], borrowing['borrowing_date'], borrowing['return_date'], borrowing['id'])) self.conn.commit() return self.cursor.rowcount # 删除借阅记录 def delete_borrowing(self, borrowing_id): sql = "DELETE FROM borrowing WHERE id=%s" self.cursor.execute(sql, (borrowing_id,)) self.conn.commit() return self.cursor.rowcount ``` BLL层 ```python from DAL import BookDAL, UserDAL, BorrowingDAL class BookBLL: def __init__(self, config): self.dal = BookDAL(config) # 获取所有图书 def get_all_books(self): return self.dal.get_all_books() # 添加图书 def add_book(self, book): return self.dal.add_book(book) # 修改图书信息 def update_book(self, book): return self.dal.update_book(book) # 删除图书 def delete_book(self, book_id): return self.dal.delete_book(book_id) class UserBLL: def __init__(self, config): self.dal = UserDAL(config) # 获取所有用户 def get_all_users(self): return self.dal.get_all_users() # 添加用户 def add_user(self, user): return self.dal.add_user(user) # 修改用户信息 def update_user(self, user): return self.dal.update_user(user) # 删除用户 def delete_user(self, user_id): return self.dal.delete_user(user_id) class BorrowingBLL: def __init__(self, config): self.dal = BorrowingDAL(config) # 获取所有借阅记录 def get_all_borrowings(self): return self.dal.get_all_borrowings() # 添加借阅记录 def add_borrowing(self, borrowing): return self.dal.add_borrowing(borrowing) # 修改借阅记录信息 def update_borrowing(self, borrowing): return self.dal.update_borrowing(borrowing) # 删除借阅记录 def delete_borrowing(self, borrowing_id): return self.dal.delete_borrowing(borrowing_id) ``` PL层 ```python from flask import Flask, request, jsonify from BLL import BookBLL, UserBLL, BorrowingBLL app = Flask(__name__) config = { 'user': 'root', 'password': '123456', 'host': 'localhost', 'database': 'library' } book_bll = BookBLL(config) user_bll = UserBLL(config) borrowing_bll = BorrowingBLL(config) @app.route('/books', methods=['GET']) def get_all_books(): books = book_bll.get_all_books() return jsonify(books) @app.route('/books', methods=['POST']) def add_book(): book = request.json book_id = book_bll.add_book(book) return jsonify({'id': book_id}) @app.route('/books', methods=['PUT']) def update_book(): book = request.json result = book_bll.update_book(book) return jsonify({'affected_rows': result}) @app.route('/books/<int:book_id>', methods=['DELETE']) def delete_book(book_id): result = book_bll.delete_book(book_id) return jsonify({'affected_rows': result}) @app.route('/users', methods=['GET']) def get_all_users(): users = user_bll.get_all_users() return jsonify(users) @app.route('/users', methods=['POST']) def add_user(): user = request.json user_id = user_bll.add_user(user) return jsonify({'id': user_id}) @app.route('/users', methods=['PUT']) def update_user(): user = request.json result = user_bll.update_user(user) return jsonify({'affected_rows': result}) @app.route('/users/<int:user_id>', methods=['DELETE']) def delete_user(user_id): result = user_bll.delete_user(user_id) return jsonify({'affected_rows': result}) @app.route('/borrowings', methods=['GET']) def get_all_borrowings(): borrowings = borrowing_bll.get_all_borrowings() return jsonify(borrowings) @app.route('/borrowings', methods=['POST']) def add_borrowing(): borrowing = request.json borrowing_id = borrowing_bll.add_borrowing(borrowing) return jsonify({'id': borrowing_id}) @app.route('/borrowings', methods=['PUT']) def update_borrowing(): borrowing = request.json result = borrowing_bll.update_borrowing(borrowing) return jsonify({'affected_rows': result}) @app.route('/borrowings/<int:borrowing_id>', methods=['DELETE']) def delete_borrowing(borrowing_id): result = borrowing_bll.delete_borrowing(borrowing_id) return jsonify({'affected_rows': result}) if __name__ == '__main__': app.run(debug=True) ``` 以上是一个大致的代码框架,供您参考。如果您有任何问题或疑问,欢迎随时与我联系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值