加载yaml字符串时跳过转换实体(使用PyYAML)

时间:2018-06-17 21:49:06

标签: python yaml

在加载yaml字符串yaml包时,是否有一种防止实体转换为python对象的好方法?特别是,我不希望将时间戳字符串转换为datetime对象。

以下是一个例子:

import yaml
yaml.load("""d: 2018-06-17\nn: 42""")

给出了

{'d': datetime.date(2018, 6, 17), 'n': 42}

但我想

{'d': '2018-06-17', n: 42}

其中日期字符串保留为字符串并转换其他类型。我不想更改输入字符串,例如,通过指定特定的数据类型。也许有一个替代的YAML加载器/解析器包。我正在使用python3.6和PyYAML == 3.12。

2 个答案:

答案 0 :(得分:2)

YAML具有多个模式,并且由于您在PyYAML中使用默认(不安全)负载,因此您将获得所有它支持的Python对象的构造,包括所需的一个到int,以及一个到datetime.time不需要的内容。

由于要转换整数,因此不能使用baseloader:

import yaml
data = yaml.load("""d: 2018-06-17\nn: 42""", Loader=yaml.BaseLoader)
print(data)

因为这可以在任何地方提供字符串:

{'d': '2018-06-17', 'n': '42'}

将匹配的datetime对象作为字符串处理可能是最简单的。在我的ruamel.yaml库中,您可以使用:

import ruamel.yaml

yaml = ruamel.yaml.YAML(typ='safe')
yaml.constructor.yaml_constructors[u'tag:yaml.org,2002:timestamp'] = \
   yaml.constructor.yaml_constructors[u'tag:yaml.org,2002:str']
data = yaml.load("""d: 2018-06-17\nn: 42""")
print(data)

如果只需要支持旧的YAML 1.1规范,则可以在PyYAML中执行相同的操作:

import yaml
import yaml.constructor
yaml.constructor.SafeConstructor.yaml_constructors[u'tag:yaml.org,2002:timestamp'] = \
    yaml.constructor.SafeConstructor.yaml_constructors[u'tag:yaml.org,2002:str']

data = yaml.safe_load("""d: 2018-06-17\nn: 42""")
print(data)

同时打印:

{'d': '2018-06-17', 'n': 42}

答案 1 :(得分:0)

我认为这种行为深深植根于YAML规范,我试过ruamel,但结果是一样的。

from ruamel.yaml import YAML
from datetime import date

yaml=YAML(typ="unsafe")
assert yaml.load("""d: 2018-06-17\nn: 42""") == \
       {'d': date(2018, 6, 17), 'n': 42}

如果我遇到此问题,我会尝试将YAML导回转换回.strftime('YYYY-MM-DD')