通过 PyYAML 创建带有别名的 yaml 文件
Creating a yaml file with aliases through PyYAML
我需要创建一个格式如下的 yaml 文件:
imager: &imager
type: "detector"
half_angle: 75 degrees
max_distance: 23000 meters
ownship: &ownship
origin: [11,11,5]
type: "uav"
vehicles:
- <<: *ownship
name: "uav1"
origin: [35.69257148103399 degrees, -117.689417544709 degrees, 5500]
sensors:
- <<: *imager
name: "imager1"
我将所有特定数据存储在 Python 类 中,所以我想我会使用 PyYAML 来简化操作。然而,当我去阅读文档时,我看到没有提到如何使用 PyYAML 处理别名。这个功能是否存在,或者我应该继续制作我自己的 yaml 编写器?
如果您的 python 数据结构包含对同一对象的多个引用,那么看起来 PyYAML 似乎做了正确的事情。例如,考虑一下:
>>> a = {'name': 'bob', 'office': '100'}
>>> b = {'president': a, 'vice-president': a}
>>> b
{'president': {'name': 'bob', 'office': '100'}, 'vice-president': {'name': 'bob', 'office': '100'}}
>>> import yaml
>>> print yaml.dump(b)
president: &id001 {name: bob, office: '100'}
vice-president: *id001
PyYAML 已经识别出 'president' 和 'vice-president' 键的值是对同一对象的引用,并创建了一个别名并适当地使用它。
首先你指定的文件不是正确的YAML。它不会读入,因为这里:
- <<: *ownship
name: "uav1"
您将顺序元素和映射元素并置,这是不允许的。如果您从第一行删除 -
,您将获得正确的 YAML 文件:
imager: &imager
type: "detector"
half_angle: 75 degrees
max_distance: 23000 meters
ownship: &ownship
origin: [11,11,5]
type: "uav"
vehicles:
- <<: *ownship
name: "uav1"
origin: [35.69257148103399 degrees, -117.689417544709 degrees, 5500]
sensors:
- <<: *imager
name: "imager1"
您无法使用 PyYAML 生成。
PyYAML 确实支持用于读写的锚点和引用。它确实支持 merge key operator <<
阅读。但是不支持合并操作符的写法
这将需要比较不同的词典,确定任何词典是否是另一个词典的完整子集(一个词典的所有键和值都在另一个词典中),然后在该子集上建立锚点并在其上添加合并运算符写另一个字典(而不是在子集中写键)。
PyYAML 中没有这样的代码可以这样做,因为它比 PyYAML 支持的共享复杂对象(dict
、list
等)使用锚点和引用要复杂得多。
My ruamel.yaml 具有 PyYAML 功能的超集,从版本 0.10 开始支持此类数据的往返。它在第一次往返时做了一些 "normalisation":
imager: &imager
type: detector
half_angle: 75 degrees
max_distance: 23000 meters
ownship: &ownship
origin: [11, 11, 5]
type: uav
vehicles:
<<: *ownship
name: uav1
origin: [35.69257148103399 degrees, -117.689417544709 degrees, 5500]
sensors:
- <<: *imager
name: imager1
读取 YAML 并操作生成的数据结构然后将其写出很容易。键的分配是在您引用的字典上完成的,如果在引用的字典中不可用,则从第一个合并的字典中透明地检索值。
从头开始创建这样的结构然后转储它更加困难,因为没有支持例程通过比较 keys/values 在字典之间创建合并(目前)。
我需要创建一个格式如下的 yaml 文件:
imager: &imager
type: "detector"
half_angle: 75 degrees
max_distance: 23000 meters
ownship: &ownship
origin: [11,11,5]
type: "uav"
vehicles:
- <<: *ownship
name: "uav1"
origin: [35.69257148103399 degrees, -117.689417544709 degrees, 5500]
sensors:
- <<: *imager
name: "imager1"
我将所有特定数据存储在 Python 类 中,所以我想我会使用 PyYAML 来简化操作。然而,当我去阅读文档时,我看到没有提到如何使用 PyYAML 处理别名。这个功能是否存在,或者我应该继续制作我自己的 yaml 编写器?
如果您的 python 数据结构包含对同一对象的多个引用,那么看起来 PyYAML 似乎做了正确的事情。例如,考虑一下:
>>> a = {'name': 'bob', 'office': '100'}
>>> b = {'president': a, 'vice-president': a}
>>> b
{'president': {'name': 'bob', 'office': '100'}, 'vice-president': {'name': 'bob', 'office': '100'}}
>>> import yaml
>>> print yaml.dump(b)
president: &id001 {name: bob, office: '100'}
vice-president: *id001
PyYAML 已经识别出 'president' 和 'vice-president' 键的值是对同一对象的引用,并创建了一个别名并适当地使用它。
首先你指定的文件不是正确的YAML。它不会读入,因为这里:
- <<: *ownship
name: "uav1"
您将顺序元素和映射元素并置,这是不允许的。如果您从第一行删除 -
,您将获得正确的 YAML 文件:
imager: &imager
type: "detector"
half_angle: 75 degrees
max_distance: 23000 meters
ownship: &ownship
origin: [11,11,5]
type: "uav"
vehicles:
- <<: *ownship
name: "uav1"
origin: [35.69257148103399 degrees, -117.689417544709 degrees, 5500]
sensors:
- <<: *imager
name: "imager1"
您无法使用 PyYAML 生成。
PyYAML 确实支持用于读写的锚点和引用。它确实支持 merge key operator <<
阅读。但是不支持合并操作符的写法
这将需要比较不同的词典,确定任何词典是否是另一个词典的完整子集(一个词典的所有键和值都在另一个词典中),然后在该子集上建立锚点并在其上添加合并运算符写另一个字典(而不是在子集中写键)。
PyYAML 中没有这样的代码可以这样做,因为它比 PyYAML 支持的共享复杂对象(dict
、list
等)使用锚点和引用要复杂得多。
My ruamel.yaml 具有 PyYAML 功能的超集,从版本 0.10 开始支持此类数据的往返。它在第一次往返时做了一些 "normalisation":
imager: &imager
type: detector
half_angle: 75 degrees
max_distance: 23000 meters
ownship: &ownship
origin: [11, 11, 5]
type: uav
vehicles:
<<: *ownship
name: uav1
origin: [35.69257148103399 degrees, -117.689417544709 degrees, 5500]
sensors:
- <<: *imager
name: imager1
读取 YAML 并操作生成的数据结构然后将其写出很容易。键的分配是在您引用的字典上完成的,如果在引用的字典中不可用,则从第一个合并的字典中透明地检索值。
从头开始创建这样的结构然后转储它更加困难,因为没有支持例程通过比较 keys/values 在字典之间创建合并(目前)。