Я пытаюсь найти способ сохранить порядок в моем ямле? когда я перебираю словарь, я получаю обратно, мой заказ неверен.

from yaml import load

def __init__(self, logger, configFilePath):
    self.config_dict = None

    with open(configFilePath) as config:
        self.config_dict = load(config)

    logger.debug('values:')  
    for key, value in self.config_dict.iteritems():
        logger.debug('- ' + key + ': ' + str(value))

    logger.debug('+++ Successfully finished +++')

def getConfig(self):
    return self.config_dict    

Пример Yaml

    repos.images:
      -
       id: Thing1
       foo: bar 
       name: Sam
      -
       id: thing2
       foo: bar
       name: dan

Вот пример того, как я называю класс. Ничего особенного. в двух словах, вместо того, чтобы сначала получить вещь1, сначала получить вещь2 ...

yamlObj = parser.config_parser(logger, theFile)
myYaml = yamlObj.getConfig()
for image in myYaml["repos.images"]:
    myStr = image["foo"] + '/' + image["id"]
    logger.debug("myStr is: " + myStr)

Есть ли способ сделать это или лучше я мог бы структурировать свой yaml?

-1
LCM 23 Фев 2018 в 02:03

3 ответа

Лучший ответ

Словари (или хэши, ключ / значение, ассоциативные массивы, карты, называйте их как хотите) обычно явно неупорядочены. Если вы действительно хотите сохранить порядок, вы можете сделать это с другой библиотекой yaml (на работе мы использовали https://pypi.python.org/pypi/ruamel.yaml для обновления" на месте "файлов yaml).

Но обязательно используйте упорядоченный словарь (python3) или другое решение для данных, как только они будут извлечены из YaML.

2
halfer 25 Янв 2019 в 23:48

Вы можете использовать namedtuple для некоторого контроля над загруженной конфигурацией. Также рассмотрите возможность использования safe_load

import collections
import yaml


file = open("./so.yaml", 'r')
cfg = yaml.safe_load(file)

Config = collections.namedtuple("Config", ["id", "foo", "name"])

cfg_lst = [Config(**x) for x in cfg["repos.images"]]

Тогда, например,

>>> print(cfg_lst)

Даст вам

>>> [Config(id='Thing1', foo='bar', name='Sam'), Config(id='thing2', foo='bar', name='dan')]

Итак, чтобы получить доступ к определенному элементу, скажем, thing2, вы получите к нему вот так

>>> print(cfg_lst[1].id)
>>> thing2
2
formi23 25 Фев 2018 в 23:32

Недавно я написал для этого библиотеку, oyaml. На оболочке:

$ pip install oyaml

В вашем коде Python это изменение одного символа:

from oyaml import load  # instead of `from yaml import load`

Затем сопоставления будут загружены в collections.OrderedDict экземпляры. вместо обычных диктовок, сохраняя их первоначальный порядок из файла конфигурации.

1
wim 23 Фев 2018 в 00:18