使用 python 从 yaml 读取并转储 [bracket, list]

Gul*_*zar 7 python yaml

我正在尝试使用以下代码读取列表并将其转储到 yaml

with open(system_bsc_path) as f:
    system_bsc_dict = yaml.load(f)
with open(system_bsc_path, "w") as f:
    yaml.safe_dump(system_bsc_dict, f)
Run Code Online (Sandbox Code Playgroud)

输入列表,如文件中所示:

chs_per_cath: [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]],
 [[16, 17, 18, 19, 20, 21, 22, 23, 24, 25], [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]],
 [[32, 33, 34, 35, 36, 37, 38, 39, 40, 41], [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]
Run Code Online (Sandbox Code Playgroud)

被正确读入python


转储的输出:

chs_per_cath:
- - - 10
    - 11
    - 12
    - 13
  - - 13000
    - 13100
    - 13200
    - 13300
- - - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
  - - 13400
    - 13500
    - 13600
    - 13700
    - 13800
    - 13900
    - 14000
    - 14100
    - 14200
    - 14300
- - - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
  - - 13400
    - 13500
    - 13600
    - 13700
    - 13800
    - 13900
    - 14000
    - 14100
    - 14200
    - 14300
Run Code Online (Sandbox Code Playgroud)

如何获得与输入相同的输出?

Ant*_*hon 7

如果您想加载,然后转储(可能在修改某些值之后),PyYAML 不是正确的工具,因为它会破坏语法表示中的许多内容。

正如您所注意到的,它将删除流程样式,但也会删除注释、锚点/别名、特定整数格式(八进制、十六进制、二进制)等。

PyYAML 中输出的流式与块式几乎无法控制。你可以拥有全块;节点集合作为流,并且您可以使用参数 to
拥有全流。default_flow_stylesafe_dump()

你最好使用ruamel.yaml(免责声明:我是该库的作者),因为它支持已有 10 年历史的 YAML 1.2 标准(其中 PyYAML 只处理过时的 YAML 1.1),并且会为你提供更接近的输出,通常与您的 YAML 输入相同。

from ruamel.yaml import YAML

yaml = YAML()
with open(system_bsc_path) as f:
    system_bsc_dict = yaml.load(f)
with open(system_bsc_path, "w") as f:
    yaml.dump(system_bsc_dict, f)
Run Code Online (Sandbox Code Playgroud)

如果你是Python 3,你可以使用:

from pathlib import Path
yaml_file = Path(system_bsc_path)
system_bsc_dict = yaml.load(yaml_file)
yaml.dump(system_bsc_dict, yaml_file)
Run Code Online (Sandbox Code Playgroud)

默认情况下,任何列表(和字典)都将是块样式,如果您想添加流式列表,那么您可以使用设置所有这些列表,或者通过在特殊内部yaml.default_flow_style = True设置流属性( )来使用精细控制.fa表示:

def FSlist(l):  # concert list into flow-style (default is block style)
    from ruamel.yaml.comments import CommentedSeq
    cs = CommentedSeq(l)
    cs.fa.set_flow_style()
    return cs

system_bsc_dict['existing_field'] = FSlist(["Boston Maestro 4000"])
Run Code Online (Sandbox Code Playgroud)