【问题标题】:Python json scheam validator issue when converting a "number"转换“数字”时的Python json模式验证器问题
【发布时间】:2020-08-10 13:53:54
【问题描述】:

我有一个如下定义的 yml 架构

"cost_center":{
         "type":"number",
         "title":"cost center",
         "required":[
            "cost_center"
         ]
      }

现在在我的 yml 文件中,如果我将成本中心定义为 701,那么它就可以正常工作:

cost_center: 701

但如果我将成本中心定义为 0701,那么它会打印 449。

cost_center: 0701

那么,我的问题是为什么额外的前导零会导致不同的值?

我正在使用下面的,根据实际文件验证我的架构

def validateConfig(configFileName):
        with open(configSchemaFile, 'r') as pub_config_schema_file:
            pubConfigSchema = json.loads(pub_config_schema_file.read())
    
        with open(configFileName, 'r') as pub_config_file:
            pubConfigJson = json.dumps(yaml.load(pub_config_file.read(), Loader=yaml.FullLoader))
            pubConfig = json.loads(pubConfigJson)
        out = {}
    
        try:
            jsonschema.validate(pubConfig, pubConfigSchema)
            out['exit_code'] = 0
            out['config'] = pubConfig
        except jsonschema.exceptions.ValidationError as e:
            out['exit_code'] = 1
            out['error'] = e.message
            print(json.dumps(out))
            raise
    
        return json.dumps(out)

response = json.loads(validateConfig(path_to_verify + "config.yml"))
if 'cost_center' in response['config']:
    local_cost_center = response['config']['cost_center']

现在,如果成本中心是 0701,这个 local_cost_center 给我 449,如果成本中心是 701(开头没有 0)给我正确的值 701

如何解决这个错误?

【问题讨论】:

  • YML 格式是基于 XML 的,看起来与您所拥有的 YAML 格式完全不同。 YAML 文件的 recommended file extension 自 2006 年以来一直是 .yaml。您还使用 EOL python 版本和尚未升级到 2009 年发布的“新”YAML 标准的解析器。

标签: python python-2.7 yaml


【解决方案1】:

通过在您的数字前面添加前导 0,该数字被解释为以 8 为底,而不是以 10 为底。

701 (base 8) = 7*8*8 + 0*8 + 1 = 449 (base 10)

虽然不知道如何解决它 - 但如果您知道原因,您可能会找到解决方案。

从这里:How to read/load yaml parameters with leading zeros as a string?

PyYAML 不会这样做(如果决定使用安全加载,ruamel.yaml 也不会这样做)。而且您很幸运,您确实为测试尝试了像 00005 这样的标量,因为 00008 将作为字符串加载(因为 PyYAML 使用 pre-2009 YAML 1.1 规范,其中 前导零表示八进制,在 YAML 1.2 八进制中以 0o) 开头,00015 在 ruamel.yaml 中加载为数字 15,在 PyYAML 中加载为数字 13:

【讨论】:

  • Artener,感谢您的解释。但是我也不知道怎么解决?我还尝试将模式定义为仅具有模式编号的字符串,它向我显示 jsonschema.exceptions.ValidationError: 701 is not of type 'string'
  • 我也尝试使用 ruamel.yaml,这忽略了前导零。所以基本上不知道。
  • @change198。你不知道什么? ruamel.yaml 做正确的事,所以使用它。
猜你喜欢
  • 2012-03-23
  • 2019-01-27
  • 2019-04-13
  • 2021-03-13
  • 2021-05-18
  • 2019-06-29
  • 2016-08-27
  • 1970-01-01
  • 2020-10-31
相关资源
最近更新 更多