web-dev-qa-db-fra.com

Conversion du fichier YAML en python dict

J'ai le problème suivant de mapper des documents dans un fichier YAML à un dict et de les mapper correctement.

J'ai le fichier YAML suivant, qui représente un serveur (db.yml):

instanceId: i-aaaaaaaa
     environment:us-east
     serverId:someServer
     awsHostname:ip-someip
     serverName:somewebsite.com
     ipAddr:192.168.0.1
     roles:[webserver,php]

Je charge ce fichier YAML, ce que je peux faire sans aucun problème, je pense que je comprends cela.

instanceId = getInstanceId()
stream = file('db.yml', 'r')
dict = yaml.load_all(stream)

for key in dict:
    if key in dict == "instanceId":
        print key, dict[key]

J'aimerais que la logique fonctionne comme suit:

  • charger yaml, carte pour dicter
  • regardez dans chaque dict du document, si le instanceId correspond à celui qui a été défini par getInstanceId(), puis imprimez toutes les clés et valeurs de ce document.

Si je regarde la structure des données cartographiques depuis la ligne de commande, j'obtiens:

{'instanceId': 'i-aaaaaaaa environment:us-east serverId:someServer awsHostname:ip-someip serverName:someserver ipAddr:192.168.0.1 roles:[webserver,php]'}

Je pense que je peux créer la structure de données pour le fichier YAML de manière incorrecte, et en faisant correspondre le contenu sur le dict, je suis un peu perdu.

Note latérale: Je ne peux pas charger tous les documents de ce fichier en utilisant yaml.load(), j'ai essayé yaml.load_all(), ce qui semble fonctionner mais mon problème principal existe toujours.

28
Zippy Zeppoli

Je pense que votre fichier yaml devrait ressembler (ou au moins quelque chose comme ça, donc il est correctement structuré de toute façon):

instance:
     Id: i-aaaaaaaa
     environment: us-east
     serverId: someServer
     awsHostname: ip-someip
     serverName: somewebsite.com
     ipAddr: 192.168.0.1
     roles: [webserver,php]

Ensuite, yaml.load(...) renvoie:

{'instance': {'environment': 'us-east', 'roles': ['webserver', 'php'], 'awsHostname': 'ip-someip', 'serverName': 'somewebsite.com', 'ipAddr': '192.168.0.1', 'serverId': 'someServer', 'Id': 'i-aaaaaaaa'}}

Et vous pouvez partir de là ...


Donc utilisé comme:

>>> for key, value in yaml.load(open('test.txt'))['instance'].iteritems():
    print key, value


environment us-east
roles ['webserver', 'php']
awsHostname ip-someip
serverName somewebsite.com
ipAddr 192.168.0.1
serverId someServer
Id i-aaaaaaaa
31
Jon Clements

Un bug supplémentaire dans votre code, qui n'a rien à voir avec YAML:

for key in dict:
    if key in dict == "instanceId": # This doesn't do what you want
        print key, dict[key]

in est un opérateur qui fonctionne sur types de séquences , ainsi que sur les cartes. C'est pourquoi ce n'est pas une erreur de syntaxe ... mais cela ne fait pas ce que vous voulez.

key in dict sera toujours évalué à True, car toutes les clés que vous parcourez sont dans le dict. Votre code se résume donc à True == "instanceId", qui sera toujours évalué à False, car la valeur booléenne True n'est jamais égale à cette chaîne.

Vous avez peut-être remarqué que l'instruction print ne produit aucune sortie; c'est parce qu'il n'est jamais appelé.

3
Michael Scheper