【问题标题】:ruamel.yaml weird behavior with datetime like valuesruamel.yaml 具有类似日期时间的值的奇怪行为
【发布时间】:2021-11-29 14:34:01
【问题描述】:

检查.py

import os
from pathlib import Path
import sys
import json

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,有错误。

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

test2.yaml,运行正常

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

test2.yaml,运行正常

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

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

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

那么 ruamel.yaml 决定将值解析为 datetime 的标准是什么?

【问题讨论】:

    标签: python yaml ruamel.yaml


    【解决方案1】:

    我不确定你认为什么奇怪的行为,ruamel.yaml 使用常规 表达式将标量隐式标记为resolver.py 中定义的时间戳。 该正则表达式改编自正则表达式 Timestamp Language Independent Type for YAML.

    正则表达式假定年份为 4 位,月份和日期最多为 2 位。有效的datetime.datedatetime.datetime(例如,没有月份 2000-12-44 与正则表达式匹配,但不是有效日期) 仅在合成阶段很晚才检查,当它失败时,标量被假定为一个字符串。

    所以2000-12-26 加载为date 是正常的,111-12-262000-12-26111 都加载 作为字符串。

    由于json.dumps() 不支持转储datetime.date 实例,您将拥有 通过指定default=str 将类型显式转换为字符串,以防止出现错误。

    在我看来,奇怪的是你假设 json.dumps() 加载了一些东西 (“json.dumps 很好地加载了 OrderedDict 数据”)。 顾名思义,该例程不加载,而是转储,并且可以 转储OrderedDict 是因为那是dict 的子类

    这样做也是低效的 print()json.dumps() 的结果 直接转储到sys.stdout

    import sys
    import json
    import ruamel.yaml
    
    yaml_strs = [
    """\
    a:
      - b: 2
      - 123
      - 2000-12-26
    """,
    """\
    a:
      - b: 2
      - 123
      - 111-12-26
    """,
    """\
    a:
      - 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]))
        try:
            json.dump(data, sys.stdout, default=str)
            print() # since json.dump doesn't write a final newline
        except TypeError as e:
            print(e)
    

    给出:

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

    【讨论】:

      猜你喜欢
      • 2014-11-23
      • 1970-01-01
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      • 2019-11-30
      • 1970-01-01
      相关资源
      最近更新 更多