为什么 yaml 无法按预期加载值?

Why the yaml can't load value as expected?

我用下一个最小的例子来解释我的问题:

test.py

#! /usr/bin/python3

import jinja2
import yaml
from yaml import CSafeLoader as SafeLoader

devices = [
    "usb_otg_path: 1:8",
    "usb_otg_path: m1:8",
    "usb_otg_path: 18",
]

for device in devices:
    template = jinja2.Template(device)
    device_template = template.render()
    print(device_template)
    obj = yaml.load(device_template, Loader=SafeLoader)
    print(obj)

运行结果为:

root@pie:~# python3 test.py
usb_otg_path: 1:8
{'usb_otg_path': 68}
usb_otg_path: m1:8
{'usb_otg_path': 'm1:8'}
usb_otg_path: 18
{'usb_otg_path': 18}

你可以看到如果device_template的值是usb_otg_path: 1:8,那么在yaml.load之后,1:8变成了68,看起来是因为我们有: 在里面。但其他2个输入没问题。

你知道上面是一个复杂系统的简化,其中"usb_otg_path: 1:8"是我无法更改的输入值,yaml.load也是它用来更改字符串的基本机制到 python 对象。

然后,如果可能的话,我可以通过一些小的更改获得 {'usb_otg_path': '1:8'}(我们需要向上游到那个项目,所以可能不能做大的更改来影响其他人)?诸如更改 yaml.load 或其他参数的任何参数?

YAML 允许格式为 x:y:z 的数字文字(标量)并将它们解释为“六十进制”,也就是说:基数 60.

1:8 因此被 YAML 解释为 1*60**1 + 8*60**0,显然给你 68.

值得注意的是,您还有 m1:8 作为字符串和 18 作为数字。你听起来像你想要所有的字符串? This answer 可能有用:

yaml.load(yaml, Loader=yaml.BaseLoader)

This disables automatic value conversion, as BaseLoader "does not resolve or support any tags and construct only basic Python objects: lists, dictionaries, and Unicode strings." - See reference below