美文网首页
py3笔记8:json结构的校验

py3笔记8:json结构的校验

作者: _百草_ | 来源:发表于2022-04-19 10:17 被阅读0次

    1. Json模块

    python中使用json模块实现python对象与json的转换

    • json.dumps():Python对象转换为Json Object(JSON字符串)
    • json.loads() :Json对象(已编码的JSON字符串)转换为python 对象
      Python 编码为 JSON 类型转换对应表:
      image.png
      JSON 解码为 Python 类型转换对应表:
      image.png
    import json
    
    res = {"success": True,
           "code": "200",
           "msg": None,
           "data": [{"belongEndCode": "EMBEDDED", "belongEndDesc": "嵌入式"},
                    {"belongEndCode": "PANEL", "belongEndDesc": "面板"},
                    {"belongEndCode": "CLOUD", "belongEndDesc": "云端"},
                    {"belongEndCode": "IOS", "belongEndDesc": "iOS"},
                    {"belongEndCode": "SMALL_PROGRAM", "belongEndDesc": "小程序"},
                    {"belongEndCode": "WEB", "belongEndDesc": "Web前端"}],
           "t": 1648869618886}
    
    json_res = json.dumps(res, ensure_ascii=False) 
    print(json_res)
    print(type(json_res))  # <class 'str'>
    # 对python而言,实际是json编码的字符串
    
    1.1 dumps的参数
    1. ensure_ascii=False, 则返回结果不含ascII字符,解决中文乱码问题。
    2. sort_keys是告诉编码器按照字典key排序(a到z)输出。
    json_res = json.dumps(res, ensure_ascii=False, sort_keys=True)  # 添加sort_keys的传参
    #输出结果
    {"code": "200", "data": [{"belongEndCode": "EMBEDDED", "belongEndDesc": "嵌入式"}, {"belongEndCode": "PANEL", "belongEndDesc": "面板"}, {"belongEndCode": "CLOUD", "belongEndDesc": "云端"}, {"belongEndCode": "IOS", "belongEndDesc": "iOS"}, {"belongEndCode": "ANDROID", "belongEndDesc": "Android"}, {"belongEndCode": "SMALL_PROGRAM", "belongEndDesc": "小程序"}, {"belongEndCode": "H5", "belongEndDesc": "H5"}, {"belongEndCode": "WEB", "belongEndDesc": "Web前端"}, {"belongEndCode": "PC", "belongEndDesc": "PC端"}], "msg": null, "success": true, "t": 1648869618886}
    
    1. indent参数根据数据格式缩进显示,读起来更加清晰, indent的值,代表缩进空格式
    json_res = json.dumps(res, ensure_ascii=False, sort_keys=True, indent=4)  # 添加indent,一般使用4代表一个Tab键的缩进
    # 输出结果:
    {
        "code": "200",
        "data": [
            {
                "belongEndCode": "CLOUD",
                "belongEndDesc": "云端"
            },
            {
                "belongEndCode": "PC",
                "belongEndDesc": "PC端"
            }
        ],
        "msg": null,
        "success": true,
        "t": 1648869618886
    }
    
    1. skipkeys参数,在encoding过程中,dict对象的key只可以是string对象,如果是其他类型,那么在编码过程中就会抛出ValueError的异常。skipkeys可以跳过那些非string对象当作key的处理.
      skipkeys
    1.2 json文件

    要处理的是文件而不是字符串,你可以使用json.dump()json.load() 来编码和解码JSON数据

    # 写入 JSON 数据
    with open('data1.json', 'w', encoding="utf-8") as f:
        json.dump(res, f)  # res为python对象
    
    # 读取数据
    with open('data1.json', 'r', encoding="utf-8") as f:
        data = json.load(f)
    

    2. JsonSchema

    Json Schema是一个用于验证Json数据结构的强大工具
    使用范围:接口测试中数据值校验、数据类型校验、json数据结构校验
    官网:https://json-schema.org/understanding-json-schema/conventions.html
    安装:pip install jsonschema

    2.1 type关键字

    type 关键字是json模式的基础,指定架构的数据类型:string、number、object、array、boolean、null

    from jsonschema import validate
    # json.dumps中indent存在是,校验json_schema也不通过
    # json.dumps中sort_keys存在时,排序也会影响校验结果
    # 不需要将python对象dumps成json
    
    res = 1
    json_schema = {"type": "string"}
    validate(res, json_schema)  # 校验,若不匹配则报错
    # jsonschema.exceptions.ValidationError: instance is not of type 'xxx'
    
    # 多个类型
    res = 2
    json_schema = {"type": ["string", "object"]}
    validate(res, json_schema)  # 校验,若不匹配则报错
    # jsonschema.exceptions.ValidationError: 2 is not of type 'string', 'object'
    

    2.2 object关键字

    object关键字,在python中对应的是dict类型

    • 属性properties
      用于定对象上的属性(即dict的键)
    res = {
        "code": "200",
        "data": [{"name": 123}, {"name", 3}],
        "msg": None,
        "success": True,
        "t": 1648869618886
    }
    json_schema = {
        "type": "object",
        "properties": {
            "code": {"type": "string"},
            "data": {"type": "array"},
            "msg": {"type": "null"},
            "success": {"type": "boolean"},
            "t": {"type": "number"}
        }
    }
    validate(res, json_schema)
    
    • 必需属性required
      properties不需由关键字定义的属性,也可以使用required关键字来提供所需属性的列表
      required 接受一个或多个字符串的数组。且每个字符串必须是唯一的。
    res = {
        "code": "200",
        "data": [{"name": 123}, {"name", 3}],
        "msg": None,
        "success": True,
        "t": 1648869618886
    }
    json_schema = {
        "type": "object",
        "required": ["t", "msg"]
    }
    validate(res, json_schema)
    # 必需属性的缺失会报错:jsonschema.exceptions.ValidationError: 'datas' is a required property
    # 必需参数不校验属性的排序
    
    • 属性数 minPropertiesmaxProperties
      限制对象上的属性数。这些中的每一都必需是非负整数
    json_schema = {
        "type": "object",
        "minProperties": 4,  # 最少
        "maxProperties": 5 # 最多
    }
    validate(res, json_schema)
    # 报错信息:jsonschema.exceptions.ValidationError: xxx has too many properties 或 xxx does not have enough properties
    

    2.3 array关键字

    数组属性array,用于有序元素
    在python中,array类似于list或tuple

    • items
      数组的元素,可能是任何类型,但根据某模式验证数组的项通常很有用。使用itemsadditionalItems关键字来完成
      items 是单个模式,针对数组中每一个项目而言

    在Json,通常有2种方式验证
    1. 列表验证:任意长度的序列,其中每个元素匹配相同的模式
    2. 元组验证:一个固定长度的序列,其中每个项目可能具有不同的模式

    # res = [1, "2", [3], {"f": 4}, (5,)]
    res = [1, "2", [3], {"f": 4}]
    # print(type(res[4]))  # <class 'tuple'>
    

    1. 列表验证

    res = [1, 2, 3, 4, 5]
     json_schema = {
         "type": "array",
         "items": {"type": "number"}
    }
     validate(res, json_schema)
    # 不匹配报错:jsonschema.exceptions.ValidationError: '2' is not of type 'number'
    

    2. 元组验证
    针对每一个元素解释说明,默认校验schema中设置的前n项
    将items关键字设置成一个数组, 其中每个项目都是一个与文档数组的每个索引相对应的模式,
    也就是一个数组, 第一个元素模式验证输入数组的第一个元素. 第二个元素模式验证输入数组的第二个元素

    json_schema = {
         "type": "array",
         "items": [
             {"type": "number"},
             {"type": "string"},
             {"type": "array", "items": {"type": "number"}},
             {"type": "object"},
             {"type": "string"}    # python中tuple对应的是json中的??
         ]
     }
     validate(res, json_schema)
    
    • additionlItems 关键字
      控制是否有超出schema中定义的数组的其他项,默认True;若设置为False,则不允许数组中的额外项
    res = [1, "2", [3], {"f": 4}, "5", (6,)]
    # validate(res, json_schema)  # 默认True,允许数组中额外项
    json_schema = {
        "type": "array",
        "items": [
            {"type": "number"},
            {"type": "string"},
            {"type": "array", "items": {"type": "number"}},
            {"type": "object"}
        ],
        "additionalItems": False
    }
    # validate(res, json_schema)
    # 校验不通过,则报错jsonschema.exceptions.ValidationError: Additional items are not allowed ('5', (6,) were unexpected)
    
    • 长度minItemsmaxitems
      每个关键字的值都必须是非负数。无论是对List还是tuple验证,这些字段都是有效的
    json_schema = {
        "type": "array",
        "minItems": 3,
        "maxItems": 3
    }
    validate(res, json_schema)
    # 校验失败,报错:jsonschema.exceptions.ValidationError: xxx is too short 或 xxx is too long
    
    • 唯一性uniqueItems
    res = [1, 1, 2]
    json_schema = {
        "type": "array",
        "uniqueItems": True
    }
    validate(res, json_schema)
    # 存在重复数据时,报错:jsonschema.exceptions.ValidationError: xxx has non-unique elements
    

    2.4 通用关键字

    • 元数据
      json模式包含几个关键字, title, descriptiondefault, 不严格用来校验格式,但用来描述模式的一部分。
      在title和description管家你必须是字符串

    • 枚举值enum
      enum关键字用于限制值, 以一个固定的一组值, 它必须是一个必须包含一个元素的数组,其中每个元素都是唯一的。

    { 
      ‘type’ : ‘string’, 
      ‘enum’: [‘red’, ‘green’] 
    }
    # 如果检验字段的值在枚举中是通过的, 如果不是无法校验通过。
    

    2.5 组合模式

    例如, 在以下的模式, anyOf关键字用于表示给定值可能对任何给定的子模式有效。第一个子模式需要一个最大长度为5的字符串。第二个子模式需要一个最小值为0的数字。只要一个值对这些模式中的任何一个进行验证,它就被认为整个组合模式有效。
    { ‘anyOf’: [ {‘type’: ‘string’, ‘maxLength’: 5}, {‘type’:’string’, ‘minimum’: 0 }]}

    用于组合模式的关键字是:

    • anyOf: 必须对任何子模式有效(一个或多个)
    • oneOf: 必须仅对其中一个子模式有效
    • allOf: 必须对所有子模式有效
    • anyOf
      要进行验证anyOf,给定数据必须对任何(一个或多个)给定子模式有效。
    {
      “anyOf” : [
        { “type” : “string” },
        { “type” : “number” }
      ]
    }
    # 如果是 “您好”, pass 
    # 如果是 33, pass 
    # 如果是 [‘ddd’, 33], false
    等同于 
    {
     “type” :[ “string” ,“number” ]
    }
    
    • oneOf
      要进行验证oneOf,给定数据必须仅对其中一个给定子模式有效。
    {
      “oneOf” : [
        { “type” : “number” , “multipleOf” : 5 },
        { “type” : “number” , “multipleOf” : 3 }
      ]  
    }
    如果是5的倍数, pass 
    如果是3的倍数, pass 
    如果是5和3的倍数, false
    
    • allOf
      要进行验证allOf,给定数据必须对所有给定的子模式有效。
    {
      “allOf” : [
        { “type” : “string” },
        { “maxLength” : 5 }
      ]
    }
    

    2.6 $schema关键字

    该$schema关键字用于声明JSON片段实际上是JSON模式的一部分。它还声明了针对该模式编写的JSON Schema标准的哪个版本。

    建议所有JSON模式都有一个$schema条目,该条目必须位于根目录下。因此,大多数情况下,您需要在架构的根目录下:

    “$ schema” : “http://json-schema.org/schema#


    3. 参考

    1. jsonschema+装饰器 实现更简单的python参数校验
    2. JsonSchema使用详解
    3. python3 json数据解析
    4. json.dumps参数说明
    5. JSON Schema 规范文档(中文版)

    相关文章

      网友评论

          本文标题:py3笔记8:json结构的校验

          本文链接:https://www.haomeiwen.com/subject/bdrnjrtx.html