微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我如何需要两个 jsonschema 属性之一,但还要设置默认值?

如何解决我如何需要两个 jsonschema 属性之一,但还要设置默认值?

我尝试验证使用 radiusdiameter 或两者都不定义圆的 jsonschema,然后仅设置认半径。这是我的架构:

{
  "properties": {
    "position": {},"radius": {
      { "type": "number" }
    },"diameter": {
      { "type": "number" }
    }
  },"oneOf": [
    {
      "required": ["radius"]
    },{
      "required": ["diameter"]
    },{
      "properties": {
        "radius": {
          "default": 16
        }
      }
    }
  ],"additionalProperties": false
}

这是设置认值的验证器(如 JSON schema FAQ 所述):

from jsonschema import Draft7Validator,validators

def extend_with_default(validator_class):
  validate_properties = validator_class.VALIDATORS['properties']

  def set_defaults(validator,properties,instance,schema):
    for property,subschema in properties.items():
      if 'default' in subschema:
        instance.setdefault(property,subschema['default'])

    for error in validate_properties(
      validator,schema,):
      yield error

  return validators.extend(
    validator_class,{'properties' : set_defaults},)
Validator = extend_with_default(Draft7Validator)

此验证器在我验证架构之前设置认值,因此我只能设置半径或两者都不设置,但是设置直径总是会引发错误。 如果我将其更改为首先验证并稍后设置认值(我宁愿不这样做,但可以),那么它会设置认半径,尽管所需的直径已经存在。

有没有办法通过在 python 中设置认半径来实现这一点,而无需对其进行硬编码?

解决方法

验证器不需要更改。这是一个可能的解决方案:

{
  "properties": {
    "position": {},"radius": {
      { "type": "number" }
    },"diameter": {
      { "type": "number" }
    }
  },"if": {
    "not": {
      "anyOf": [
        {
          "required": ["radius"]
        },{
          "required": ["diameter"]
        }
      ]
    }
  },"then": {
    "properties": {
      "radius": {
        "default": 16
      }
    }
  },"oneOf": [
    {
      "required": ["radius"]
    },{
      "required": ["diameter"]
    }
  ],"additionalProperties": false
}

if 仅在半径或直径均未设置的情况下为真。只有这样才会设置默认半径。然后 oneOf 检查是否只有一个参数同时被设置。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。