使用Python输出YAML:格式错误,输入中没有列表

时间:2019-02-06 02:20:11

标签: python yaml pyyaml ruamel.yaml

我正在尝试从Python字典创建YAML。到目前为止,我已经尝试了PyYAML和ruamel.yaml,它们都具有相同的结果:如果输入字典不包含列表,则输出的格式不正确。

这是脚本:

$.post('/FootballLeagueController', {PlayerData: JSON.stringify(Record)})

这是输出:

from ruamel import yaml
import sys

yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'armament': ['photon torpedoes','phasers'], 'number': 1701}, sys.stdout)
print('\n')
yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'number': 1701}, sys.stdout)

所需的输出是第二个YAML转储的格式应与第一个一样。这是怎么回事?

2 个答案:

答案 0 :(得分:1)

您使用的是旧式API,默认情况下会输出任何叶子 流样式中的节点。在您的情况下,列表/序列[photon torpedoes, phasers]和秒转储(根级别 叶节点)。


假设您不仅想要解释为什么会发生这种情况,还想要了解如何使用新的API(使用ruamel.yaml.YAML实例来更改此行为),默认设置是使所有内容成为流式,包括所有叶节点:

from ruamel.yaml import YAML
import sys

yaml = YAML()

yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'armament': ['photon torpedoes','phasers'], 'number': 1701}, sys.stdout)
print()
yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'number': 1701}, sys.stdout)

给予:

name: Enterprise
class: Galaxy
armament:
- photon torpedoes
- phasers
number: 1701

name: Enterprise
class: Galaxy
number: 1701

仍然不是您想要的东西:-)

您现在有两种选择来获得所指示的内容:第一个转储上的叶子节点流样式和第二个上的叶子节点块样式。

第一个方法是为第一个转储使用一个实例default_flow_style集, 第二个转储是“正常”的:

from ruamel.yaml import YAML
import sys

yaml = YAML()

yaml.default_flow_style = None
yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'armament': ['photon torpedoes','phasers'], 'number': 1701}, sys.stdout)
print()
yaml = YAML()
yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'number': 1701}, sys.stdout)

给出:

name: Enterprise
class: Galaxy
armament: [photon torpedoes, phasers]
number: 1701

name: Enterprise
class: Galaxy
number: 1701

第二个选项是显式设置对象的流样式 您要作为序列输出的内容。因此,您必须创建一个 ruamel.yaml.comments.CommentedSeq实例,通常使用 加载时保留流/块样式,注释等:

from ruamel.yaml import YAML, comments
import sys

yaml = YAML()

armaments = comments.CommentedSeq(['photon torpedoes','phasers'])
armaments.fa.set_flow_style()
yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'armament': armaments, 'number': 1701}, sys.stdout)
print()
yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'number': 1701}, sys.stdout)

这还提供:

name: Enterprise
class: Galaxy
armament: [photon torpedoes, phasers]
number: 1701

name: Enterprise
class: Galaxy
number: 1701

第二个选项当然可以让您在操作时进行精细控制(还有一个CommentedMap) 可以在数据层次结构的各个级别上拥有这些对象,而不仅仅是在集合的叶子上。


请注意,当从具有所需格式的YAML文件中加载所需的输出时,无需经历任何这些滑稽动作。在这种情况下,字典就可以了。像实例这样的列表是用正确的流程/块样式创建的,因此,仅更改/添加值并转回时,输出不会意外更改。

答案 1 :(得分:0)

documentation中说明了如何获得一致的输出:

yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'number': 1701},
  sys.stdout,
  default_flow_style=False) # <- the important parameter

class: Galaxy
name: Enterprise
number: 1701