加载 YAML 保留顺序

Dav*_*cía 6 python yaml configuration-files

我有一个 Python 库,它定义了一个类似于下一个列表的列表:

config = [
    'task_a',
    ('task_b', {'task_b_opt_1': ' '}),
    ('task_a', {'task_a_opt_1': 42}),
    ('task_c', {'task_c_opt_1': 'foo', 'task_c_opt_2': 'bar'}),
    'task_b'
]
Run Code Online (Sandbox Code Playgroud)

基本上,此列表定义了 5 个必须按特定顺序应用并使用定义的参数(如果有)的任务。此外,同一任务可以定义或不定义参数(使用默认值)。

现在我想扩展库以支持配置文件。为了让最终用户更容易使用 YAML 文件,我正在考虑使用它们。所以上面的代码会变成这样:

task_a:
task_b:
  task_b_opt_1: ' '
task_a:
  task_a_opt_1: 42
task_c:
  task_c_opt_1': 'foo'
  task_c_opt_2': 'bar'
task_b:
Run Code Online (Sandbox Code Playgroud)

这甚至不是有效的 YAML 文件,因为某些键没有值。所以我有两个问题:

  1. 如何定义空任务?
  2. 在 Python 中加载文件时如何保留顺序?

如果这些都不可能,还有其他解决方案吗?

Dan*_*l H 4

在 YAML 中,映射被定义为无序的。典型的解决方案是使其成为映射列表。但是,值(甚至键)可能会丢失,在这种情况下它们是隐式的null(相当于NonePython 中的)

- task_a:
- task_b:
    task_b_opt_1: ' '
- task_a:
    task_a_opt_1: 42
- task_c:
    task_c_opt_1: 'foo'
    task_c_opt_2: 'bar'
- task_b:
Run Code Online (Sandbox Code Playgroud)

另一种选择是不将没有选项的任务放入映射中,而是使用字符串,只需:从这些行中删除:

- task_a
- task_b:
    task_b_opt_1: ' '
- task_a:
    task_a_opt_1: 42
- task_c:
    task_c_opt_1: 'foo'
    task_c_opt_2: 'bar'
- task_b
Run Code Online (Sandbox Code Playgroud)