使用 Python 输出 YAML:格式不正确,输入中没有列表
Outputting YAML with Python: incorrect formatting without lists in input
我正在尝试从 Python 字典创建 YAML。到目前为止,我已经尝试了 PyYAML 和 ruamel.yaml 并且都具有相同的结果:如果输入字典不包含列表,则输出格式不正确。
脚本如下:
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)
这是输出:
armament: [photon torpedoes, phasers]
class: Galaxy
name: Enterprise
number: 1701
{class: Galaxy, name: Enterprise, number: 1701}
所需的输出是第二个 YAML 转储的格式应与第一个相同。这是怎么回事?
这在 documentation 中关于如何进行一致输出的说明:
yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'number': 1701},
sys.stdout,
default_flow_style=False) # <- the important parameter
class: Galaxy
name: Enterprise
number: 1701
您正在使用旧样式 API 并且默认输出 any leaf
流式节点。在你的情况下 list/sequece [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
集的一个实例用于第一个转储和
"normal" 一个用于第二个转储:
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
实例,正常使用
加载时保留flow/block-style、评论等:
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 文件加载所需输出时,您不必经历任何这些滑稽动作。在那种情况下, dict resp。类似实例的列表是使用正确的 flow/block-style 创建的,因此当仅 changing/adding 一个值并转储时,输出不会意外更改。
我正在尝试从 Python 字典创建 YAML。到目前为止,我已经尝试了 PyYAML 和 ruamel.yaml 并且都具有相同的结果:如果输入字典不包含列表,则输出格式不正确。
脚本如下:
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)
这是输出:
armament: [photon torpedoes, phasers]
class: Galaxy
name: Enterprise
number: 1701
{class: Galaxy, name: Enterprise, number: 1701}
所需的输出是第二个 YAML 转储的格式应与第一个相同。这是怎么回事?
这在 documentation 中关于如何进行一致输出的说明:
yaml.dump({'name': 'Enterprise', 'class': 'Galaxy', 'number': 1701},
sys.stdout,
default_flow_style=False) # <- the important parameter
class: Galaxy
name: Enterprise
number: 1701
您正在使用旧样式 API 并且默认输出 any leaf
流式节点。在你的情况下 list/sequece [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
集的一个实例用于第一个转储和
"normal" 一个用于第二个转储:
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
实例,正常使用
加载时保留flow/block-style、评论等:
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 文件加载所需输出时,您不必经历任何这些滑稽动作。在那种情况下, dict resp。类似实例的列表是使用正确的 flow/block-style 创建的,因此当仅 changing/adding 一个值并转储时,输出不会意外更改。