【问题标题】:YAML unnamed object in list列表中的 YAML 未命名对象
【发布时间】:2021-07-07 03:12:31
【问题描述】:

我将 PyYAML 5.4.1 与 Python 3.7.3 一起使用,但在获取所需的 YAML 输出时遇到了问题。我想要一个列表中的“未命名对象”(不知道如何表达),如下所示:

- 
  a: 1
  b: 2

但我不断得到以下输出的变化:

>>> import yaml
>>> print(yaml.dump([{'a': 1, 'b': 2}]))
- a: 1
  b: 2

奇怪的是,当我走另一条路时,我使用两个不同的输入得到了相同的结果:

>>> x = '''
... -
...   a: 1
...   b: 2
... '''
>>> print(yaml.load(x, Loader=yaml.Loader))
[{'a': 1, 'b': 2}]

>>> y = '''
... - a: 1
...   b: 2
... '''
>>> 
>>> print(yaml.load(y, Loader=yaml.Loader))
[{'a': 1, 'b': 2}]

【问题讨论】:

  • yaml.load 接受任何一个,因为这只是格式的不同。两者之间没有语义差异,我不知道有一个选项可以让yaml.dump 产生额外的空白行。

标签: python yaml


【解决方案1】:

YAML 允许在块序列项中紧凑的内联表示法。也就是说,如果你的序列项包含这样的映射

- 
  a: 1
  b: 2

您可以直接在带有序列项指示符的行上开始映射:

- a: 1
  b: 2

紧凑表示法去除了映射的标题行,其中可能包含映射的锚点和/或标记,例如

- &a !!map
  a: 1
  b: 2

由于您没有使用这些功能,因此紧凑内联表示法是完全有效的,并且正如您自己发现的那样,它与序列指示器行上带有空标题的非紧凑表示法具有相同的语义。

将此与您无法发出 cmets 的事实进行比较,但使用 cmets 的输入仍会加载与没有 cmets 的输入相同的数据。你的问题就是这样,只是用空格而不是 cmets。 PyYAML 不提供修改此行为的选项,因此您无法使用它来生成所需的确切输出,但这无关紧要,因为您 能够生成等效输出。如果出于某种原因,您需要完全控制输出,那么 YAML 对您来说是错误的工具,您需要使用 XML 之类的东西,它确实定义了其词法结构的完整模型,因此允许您严格控制输出中的空格.

顺便说一句,“未命名对象”在 YAML 上下文中不是一个有意义的术语,因为没有“命名对象”。 YAML 的结构是一个节点图,其中节点可以是标量、映射或序列。序列包含子节点列表,映射包含键值对列表,其中键和值都是节点。在a: 1 中,a 不是名称,而是标量节点。写[a, b]: 1 是有效的 YAML,这表明密钥不是名称,而是某种节点。

【讨论】:

  • 感谢您的详细回复。我意识到 YAML 无论如何都是有效的,但我希望(可能是不必要的)对输出的特定外观有更多的控制。
猜你喜欢
  • 1970-01-01
  • 2015-08-16
  • 2017-11-07
  • 2020-11-06
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
相关资源
最近更新 更多