在Python中禁用YAML文件别名

3

我有一个问题,希望在我的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]

当我每次将代理达到目标点的值更新为起始点的值时,我会遇到别名成为起始点和目标点值而不是我想要的值的问题,即 [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]

预期的输出:

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]

我有以下代码,在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 {}

    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
1个回答

5
ruamel.yaml的表示器阶段会创建别名,但对于每个数据块,它都会使用ignore_aliases方法(默认为False)来检查是否应忽略该数据块的别名。
以下代码中我抑制了所有别名,但你可以根据所代表数据的(类型)情况来决定是否添加别名。这只是展示原理,你不必先写带有别名的YAML版本,只需添加以下代码即可。
yaml.representer.ignore_aliases = lambda *data: True

任何时候在实例化后(包括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)

这给出了:

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]

需要注意的是,如果你有自递归数据,你将不得不等待很长时间才能写入文件(当然这取决于你的硬盘容量)。


嗨,安东,非常感谢。我添加了代码,它可以工作了! - Tan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接