Estoy tratando de encontrar una manera de preservar el orden en mi yaml? cuando itero el diccionario, recibo mi orden incorrecta.

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    

Ejemplo de Yaml

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

Aquí hay un ejemplo de cómo llamo a la clase. No es nada lujoso. en pocas palabras, en lugar de obtener la cosa1 primero, obtengo la cosa2 primero ...

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)

¿Hay alguna manera de hacer esto o hay una mejor manera de estructurar mi yaml?

-1
LCM 23 feb. 2018 a las 02:03

3 respuestas

La mejor respuesta

Los diccionarios (o hashes, clave / valor, matrices asociativas, mapas, llámelos como quiera) generalmente no están ordenados explícitamente. Si realmente desea que se mantenga el orden, es posible que pueda hacerlo con una biblioteca yaml diferente (en el trabajo hemos utilizado https://pypi.python.org/pypi/ruamel.yaml para realizar actualizaciones" en el lugar "de los archivos yaml).

Pero asegúrese de usar también un diccionario ordenado (python3) u otra solución para los datos una vez que se extraiga de YaML.

2
halfer 25 ene. 2019 a las 23:48

Puede usar namedtuple para tener cierto control sobre su configuración cargada. Además, considere usar 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"]]

Entonces, por ejemplo,

>>> print(cfg_lst)

Te daría

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

Entonces, para acceder a un elemento en particular, digamos, thing2, lo verás así

>>> print(cfg_lst[1].id)
>>> thing2
2
formi23 25 feb. 2018 a las 23:32

Recientemente escribí una biblioteca para esto, oyaml. En la cáscara:

$ pip install oyaml

En su código de Python, es un cambio de un carácter:

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

Luego, las asignaciones se cargarán en collections.OrderedDict en lugar de dictados regulares, preservando su orden original del archivo de configuración.

1
wim 23 feb. 2018 a las 00:18