Skip converting entities while loading a yaml string (using PyYAML)

des*_*ato 7 python yaml

Is there a nice way to prevent the conversion of entities to python objects while loading a YAML string the yaml package? Particularily, I do not want the conversion of timestamp-strings to datetime objects.

Here is an example:

import yaml
yaml.load("""d: 2018-06-17\nn: 42""")
Run Code Online (Sandbox Code Playgroud)

which gives

{'d': datetime.date(2018, 6, 17), 'n': 42}
Run Code Online (Sandbox Code Playgroud)

but I would like to have

{'d': '2018-06-17', n: 42}
Run Code Online (Sandbox Code Playgroud)

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

Ant*_*hon 5

YAML 有几个模式,并且由于您在 PyYAML 中使用默认(不安全)加载,因此您可以获得它支持的 Python 对象的所有构造,包括int您想要的和datetime.time不想要的。

由于您希望转换整数,因此不能使用 baseloader:

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

因为这在任何地方都给出了字符串:

{'d': '2018-06-17', 'n': '42'}
Run Code Online (Sandbox Code Playgroud)

将匹配的日期时间对象作为字符串处理可能是最简单的。在我的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)
Run Code Online (Sandbox Code Playgroud)

如果你只需要支持旧的 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)
Run Code Online (Sandbox Code Playgroud)

都打印:

{'d': '2018-06-17', 'n': 42}
Run Code Online (Sandbox Code Playgroud)