Отключение псевдонима для файла yaml в python - PullRequest
2 голосов
/ 25 сентября 2019

У меня есть проблема, я хочу предотвратить появление псевдонимов в моем файле 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]

Как я обновляю 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]

Предполагаемый вывод:

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 Ответ

1 голос
/ 25 сентября 2019

Этап представления 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]

Будьте внимательны, хотя, если у вас есть самовосстанавливающиеся данные, вам придется долго ждать, пока ваш файл будет записан (в зависимости, конечно, от емкости вашего диска).

...