添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
from ruamel.yaml import YAML yaml = YAML(pure=True) yaml.sort_base_mapping_type_on_output = None yaml.indent(mapping=2, sequence=4, offset=2) def yamlCheck(file: os.PathLike): with open(file, 'r', encoding='utf8') as yr: data = yaml.load(yr) print(data) check = json.dumps(data, indent=4, ensure_ascii=False) print(check) if __name__ == "__main__": yamlCheck('test.yaml')

test1.yaml,有错误。

- b: 2 - 123 - 2000-12-26

test2.yaml,运行正常

- b: 2 - 123 - 111-12-26

test2.yaml,运行正常

- b: 2 - 123 - 2000-12-26111

runs ok 表示代码运行无误,json.dumps加载OrderedDict数据良好。

输出为 print(data) 。我认为ruamel.yaml已经将xxxx-xx-xx格式的数据解析为数据时间,并用它构造了一个数据时间对象,这导致了json.dumps函数的错误。

那么,ruamel.yaml的标准是什么,决定将值解析为数据时间?

python
yaml
ruamel.yaml
Puter.B166ER
Puter.B166ER
发布于 2021-10-10
1 个回答
Anthon
Anthon
发布于 2021-10-11
已采纳
0 人赞同

我不知道你认为什么是奇怪的行为, ruamel.yaml 使用正则表达式 正则表达式来隐含地将一个标量标记为时间戳,正如在 resolver.py 中定义的那样。 这个正则表达式是由 resolver.py 中的正则表达式改编的。 YAML的时间戳语言独立类型 .

该词条假定年份为4位,月份和日期最多为2位。一个有效的【替换代码2 或 datetime.datetime (例如,没有2000-12-44这个月份符合重合词,但不是有效的日期) 只在合成阶段的后期进行检查,当它失败时,标量被假定为一个字符串。

因此, 2000-12-26 作为 date 加载是正常的,而 111-12-26 2000-12-26111 都作为字符串加载。 作为字符串加载。

由于 json.dumps() 不支持转储 datetime.date 实例,你将不得不 你必须通过指定 default=str 来明确地将这些类型转换为字符串,以防止你得到的错误。

在我看来,奇怪的是,你认为 json.dumps() 加载了一些东西 ("json.dumps加载OrderedDict数据")。 这个例程并不加载,而是转储,正如它的名字所暗示的,而且它可以 dump OrderedDict 是因为它是 dict 的一个子类。

这也是一种低效率的做法,因为 替换代码14】的结果,而不是直接倾销给 json.dumps() 。 而不是直接转储到 sys.stdout

import sys
import json
import ruamel.yaml
yaml_strs = [
  - b: 2
  - 123
  - 2000-12-26
  - b: 2
  - 123
  - 111-12-26
  - b: 2
  - 123
  - 2000-12-26111
yaml = ruamel.yaml.YAML()
for yaml_str in yaml_strs:
    data = yaml.load(yaml_str)
    print(type(data['a'][2]))
        json.dump(data, sys.stdout, default=str)
        print() # since json.dump doesn't write a final newline
    except TypeError as e:
        print(e)

which gives:

<class 'datetime.date'>
{"a": [{"b": 2}, 123, "2000-12-26"]}