2015-06-18 2 views
4

Мне нужно создать YAML файл в следующем формате:Создание YAML файл с псевдонимами через PyYAML

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. Имеет ли эта функциональность, или я должен просто пойти и сделать своего собственного писателя ямля?

+0

Я обновил свой ответ, так как моя библиотека ruamel.yaml (которая имеет надстройку функций PyYAML) теперь имеет возможность обойти этот файл без потери слияния и привязки/справочной информации. Создание с нуля сложнее, но вы можете легко начать с шаблона YAML-файла, прочитать его и сохранить. – Anthon

+0

Я отправил этот ответ по аналогичному вопросу http: // stackoverflow.com/a/36295979/150050 – aaa90210

ответ

3

Прежде всего, указанный вами файл не соответствует 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<< для чтения. Но это не поддерживает запись оператора слияния.

Для этого потребуется сравнить различные словари, определяющие, является ли какой-либо dict полным подмножеством (все ключи и значения того, что находится в другом) другого dict, а затем делает привязку к подмножеству и добавляет оператор слияния при записи другой dict (и не записывая ключи в подмножество). В PyYAML такого кода нет, так как это намного сложнее, чем использование якорей и ссылок на общие сложные объекты (dict, list и т. Д.), Которые поддерживает PyYAML.

My ruamel.yaml, который имеет надстройку функциональности PyYAML, поддерживает круговое отключение таких данных, начиная с версии 0.10. Это делает некоторые «нормализацию» на первом редиректа:

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 и манипулировать полученную структуру данных, а затем записать его. Назначение ключей выполняется в словаре, который вы ссылаетесь, извлечение значения прозрачно выполняется из первого объединенного словаря, если оно не доступно в указанном словаре.

Создание такой структуры с нуля, а затем ее сброс сложнее, так как нет никаких подпрограмм для создания объединений путем сравнения ключей/значений между словарями (пока).

+0

Поддерживает ли ruamel.yaml пользовательские загрузчики и пользовательские презентаторы, как это делает PyYAML? На данный момент мне нужно иметь возможность сохранять порядок моих элементов (следовательно, мне нужен пользовательский загрузчик OrderedDict), согласованная цитированная презентация, а также сохранение операторов слияния, привязки и ссылок. – skeletalbassman

+0

@skeletalbassman Да, он имеет ту же настройку для погрузчиков/презентаторов. Источники не так сильно отличаются. Я не уверен, что ваша точная интерпретация «согласованной цитированной презентации» (я видел, как люди ожидают, что ключевые скаляры будут не кавычками, а скаляры значений будут указаны в одном и том же сопоставлении). Попробуйте и поставите вопрос на [так], если что-то не сразу работает так, как ожидалось. – Anthon

1

Похоже, что PyYAML делает все правильно, если ваша структура данных python содержит несколько ссылок на один и тот же объект. Рассмотрим, например, это:

>>> 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 признал, что значения как «президент» и ключей «вице-президент» ссылки на тот же объект, и создал псевдоним и использовать его соответствующим образом.

+0

Общие объекты не являются проблемой, это ключ слияния ('<<'), который вообще не поддерживается при записи. – Anthon

+0

Ах, извините. Я пропустил именно то, что вы хотели; вы прямо спрашивали об псевдонимах. – larsks

 Смежные вопросы

  • Нет связанных вопросов^_^