【问题标题】:Why the yaml can't load value as expected?为什么 yaml 无法按预期加载值?
【发布时间】:2020-11-24 04:56:13
【问题描述】:

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

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 的任何参数或其他什么?

【问题讨论】:

    标签: python yaml jinja2


    【解决方案1】:

    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)

    这将禁用自动值转换,因为 BaseLoader “不解析或支持任何标签,并且仅构造基本的 Python 对象:列表、字典和 Unicode 字符串。” - 请参阅下面的参考

    【讨论】:

    • 哇,它有效,谢谢~~ 对我来说,int 或 string 都可以。
    • 六进制在 YAML 1.1 规范中。十年前,它已被 YAML 1.2 取代,不再支持它们。 OP 的真正问题是使用过时的 YAML 解析器。
    • @Anthon 如何确认 yaml 规范?我用Python 3.7.3 (default, Dec 20 2019, 18:57:59)python3 -c "import yaml; print(yaml.__version__)"打印3.13,你的意思是python3的yaml库老是用10年前的1.1旧规范?
    • @Anthon 谢谢你的信息,你是对的,从pypi.org/project/PyYAML,我看到了PyYAML features a complete YAML 1.1 parser。不幸的是,这是一个开源项目,它仍然使用我无法控制的 pyyaml。感谢您提供信息。
    • @atline 如果您可以更改它,那么您将不得不解决它。 IIRC PyYAML 拒绝加载标记为 %YAML 1.2 的文档,但我不确定(它应该发出警告并尝试加载)。当您转储并明确要求 TAG 时,它将输出 %YAML 1.1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 2019-08-29
    相关资源
    最近更新 更多