栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

json结构对比

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

json结构对比

class JsonCompareUtil:
    @classmethod
    def compareValues(cls, source, target, *ignores, path='', compare_result = []):
        """
        递归对比两个json串的value
        :param source: 比较的模板json
        :param target: 目标json
        :param ignores: 忽略对比的key
        :param path: 不用传
        :param compare_result: 不用传
        :return: 对比结果列表说明,如果全部匹配返回空列表
        """
        if not isinstance(source, (list, tuple, dict, set)):
            # 比对非list、tuple、dict、set类型的数据
            if not source == target:
                msg = {
                    'field': path,
                    'error_type': '值不相等',
                    'source': source,
                    'target': target
                }
                compare_result.append(msg)
        elif isinstance(source, (list, tuple, set)):
            #类型是否一致
            if type(source) != type(target):
                msg = {
                    'field': path,
                    'error_type': "类型不一致",
                    'source': f"类型={type(source)}",
                    'target': f"类型={type(target)}"
                }
                compare_result.append(msg)
                return

            #长度是否一致
            if len(source) != len(target):
                msg = {
                    'field': path,
                    'error_type': "数组长度不一致",
                    'source': f"数组长度={len(source)}",
                    'target': f"数组长度={len(target)}"
                }
                compare_result.append(msg)
                return

            #值是否一致
            for index, value in enumerate(source):
                if index < len(target):
                    cls.compareValues(value, target[index], *ignores, path = f'{path}[{index}]' if path else f'{index}')
                else:
                    cls.compareValues(value, {}, *ignores, path = f'{path}[{index}]' if path else f'{index}')
        else:
            #比对值为dict类型数据
            if not isinstance(target, dict):
                msg = {
                    'field': path,
                    'error_type': "目标不是dict",
                    'source': f"源类型={type(source)}",
                    'target': f"目标类型={type(target)}"
                }
                compare_result.append(msg)
                return

            source_keys = source.keys()
            target_keys = target.keys()
            #求差集
            diff_keys = list(source_keys ^ target_keys)

            #有key不同
            if diff_keys:
                for key in diff_keys:
                    msg = {
                        'field': f"{path}.{key}" if path else f'{key}',
                        'error_type': '字段缺失',
                        'source': f"字段[{key}]缺失",
                        'target': target.get(key, None)
                    }
                    compare_result.append(msg)
            #key都相同,递归处理
            else:
                for key, value in source.items():
                    if key in ignores:
                        continue

                    if key in target.keys():
                        cls.compareValues(value, target[key], *ignores, path = f"{path}.{key}" if path else f'{key}')
                    else:
                        msg = {
                            'field': f"{path}.{key}" if path else f'{key}',
                            'error_type': '字段缺失',
                            'source': value,
                            'target': f"字段[{key}]缺失"
                        }
                        compare_result.append(msg)

            return compare_result


    @classmethod
    def compareKeys(cls, source, target, path='', compare_result = []):
        """
        递归对比两个json的结构
        :param source: 比较的模板json
        :param target: 目标json
        :param path: 不用传
        :param compare_result: 不用传
        :return: 对比结果列表说明,如果全部匹配返回空列表
        """
        #数组
        if isinstance(source, list) and isinstance(target, list):
            #递归处理里面的dict
            for a, b in zip(source, target):
                cls.compareKeys(a, b, path=path)

        if isinstance(source, dict) and isinstance(target, dict):
            source_keys = source.keys()
            target_keys = target.keys()
            #求差集
            diff_keys = list(source_keys ^ target_keys)
            #有key不同
            if diff_keys:
                for key in diff_keys:
                    msg = {
                        'field': f"{path}.{key}" if path else f'{key}',
                        'error_type': '字段缺失',
                        'source': f"字段[{key}]缺失",
                        'target': target.get(key, '')
                    }
                    compare_result.append(msg)
            #key都相同,递归处理
            else:
                for key, value in source.items():
                    #字典嵌套
                    if isinstance(value, dict):
                        cls.compareKeys(value, target.get(key), path=f'{path}.{key}' if path else key)
                    #列表中包含字典
                    elif isinstance(value, list):
                        cls.compareKeys(value, target.get(key), path=f'{key}[*]')

        return compare_result

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/980089.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号