在 python 中禁用 yaml 文件的别名

Tan*_*Tan 3 python yaml ruamel.yaml

我有一个问题,我希望防止 YAML 文件中出现别名。无论如何,我可以禁用生成的 YAML 文件中的别名,以实现预期的输出吗?

我当前的 YAML 文件如下:

agents:
-   start: [0, 0]
    goal: [2, 0]
    name: agent0
-   start: [2, 0]
    goal: [0, 0]
    name: agent1
map:
    dimensions: [3, 3]
    obstacles:
    - !!python/tuple [0, 1]
    - !!python/tuple [2, 1]
Run Code Online (Sandbox Code Playgroud)

当我更新每个代理的 YAML 文件时,每当他们达到目标点时,我都会遇到别名是起始值和目标值而不是我想要的值的问题,即为[0,0]开始,[0,0]为目标。

agents:
- start: &id001 [2, 0]
  goal: *id001
  name: agent0
- start: &id002 [0, 0]
  goal: *id002
  name: agent1
map:
  dimensions: [3, 3]
  obstacles:
  - !!python/tuple [0, 1]
  - !!python/tuple [2, 1]
Run Code Online (Sandbox Code Playgroud)

预期输出:

agents:
- start: [2, 0]
  goal: [2, 0]
  name: agent0
- start: [0, 0]
  goal: [0, 0]
  name: agent1
map:
  dimensions: [3, 3]
  obstacles:
  - !!python/tuple [0, 1]
  - !!python/tuple [2, 1]
Run Code Online (Sandbox Code Playgroud)

我在 Python 中运行以下代码来更新文件:

def updateInput(self, agent):
        yaml = ruamel.yaml.YAML()
        with open('input.yaml') as f:
            doc = yaml.load(f)
            self.get_updated_dict(doc, agent)

        with open('input.yaml', 'w') as y:
            yaml.dump(doc, y)

        return {}
Run Code Online (Sandbox Code Playgroud)
    def get_updated_dict(self, doc, agent):
        obj = doc
        if obj["agents"][0]["name"] == agent:
            goal_state = obj["agents"][0]["goal"]
            obj["agents"][0]["start"] = goal_state   
        return doc
Run Code Online (Sandbox Code Playgroud)

Ant*_*hon 6

ruamel.yaml 的表示阶段创建别名,但对于每条数据,它都会使用该ignore_aliases方法检查(默认为False)检查是否应忽略该数据的别名。

在下文中,我抑制了所有别名,但您可以使其依赖于所表示的数据(类型)。(这只是说明了原理,您不必首先编写带有别名的 YAML 版本,只需添加行

yaml.representer.ignore_aliases = lambda *data: True
Run Code Online (Sandbox Code Playgroud)

实例化后的任何地方yaml

import sys
import ruamel.yaml

yaml_str = """\
agents:
- start: &id001 [2, 0]
  goal: *id001
  name: agent0
- start: &id002 [0, 0]
  goal: *id002
  name: agent1
map:
  dimensions: [3, 3]
  obstacles:
  - !!python/tuple [0, 1]
  - !!python/tuple [2, 1]
"""

yaml = ruamel.yaml.YAML()
yaml.representer.ignore_aliases = lambda *data: True
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
Run Code Online (Sandbox Code Playgroud)

这使:

agents:
- start: [2, 0]
  goal: [2, 0]
  name: agent0
- start: [0, 0]
  goal: [0, 0]
  name: agent1
map:
  dimensions: [3, 3]
  obstacles:
  - !!python/tuple [0, 1]
  - !!python/tuple [2, 1]
Run Code Online (Sandbox Code Playgroud)

但请注意,如果您有自递归数据,您将不得不等待很长时间才能写入文件(当然取决于您的光盘容量)。