2012-10-22 11 views
8

Mam następujący problem mapowania dokumentów w pliku YAML na dict i prawidłowego mapowania ich.Konwertowanie pliku YAML na python dict

Mam następujący plik YAML, który reprezentuje serwer (db.yml):

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

załadować ten plik YAML, co mogę zrobić bez problemu, myślę, że rozumiem.

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] 

Chciałbym logikę pracować tak: YAML

  • obciążenia, mapa do dict
  • wygląd w każdej dict w dokumencie, jeśli instanceId pasuje do tego, który został ustalony przez getInstanceId(), a następnie wydrukuj wszystkie klucze i wartości dla tego dokumentu.

Jeśli spojrzymy na strukturę danych map z wiersza poleceń, otrzymuję:

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

myślę, że może być utworzenie struktury danych dla pliku YAML nieprawidłowo, a na dopasowanie zawartości na dict, jestem trochę zagubiony.

Uwaga boczna: Nie mogę załadować wszystkich dokumentów w tym pliku przy użyciu yaml.load(), próbowałem yaml.load_all(), który wydaje się działać, ale mój główny problem nadal istnieje.

+3

Proszę zmienić nazwę "dyktować" na coś innego. To źle.Ponadto możesz wydrukować wartość 'yaml.load_all (stream)', abyśmy mogli zobaczyć, co faktycznie masz? Na koniec nie wydaje się, że masz dobry przykład YAML - gdzie zdefiniowano wiele serwerów? – gahooa

+0

Zmienię nazwę, dziękuję za najlepszą praktykę. yaml_load_all (stream) pokazuje: . Usunąłem drugi dokument, aby rozwiązać problem. –

+0

Jaka biblioteka/moduł jest używana w kodzie? Myślę, że poprawiłoby to pytanie, aby dodać oświadczenie o imporcie, aby osoby, które znalazły to pytanie, nie musiały go szukać i potencjalnie znaleźć wiele możliwych. – Zelphir

Odpowiedz

13

myślę plik yaml powinien wyglądać (lub przynajmniej coś podobnego, więc jest skonstruowany poprawnie i tak):

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

Następnie yaml.load(...) powraca:

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

I można przejść od tam ...


Tak używane:

>>> 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 
+0

Hmm, próbowałem tego, ale nie otrzymałem tego samego wyniku za pomocą yaml, którego użyłeś powyżej: https://gist.github.com/3934903 –

+0

@zippy Skąd pochodzi ten plik yaml? –

+0

Ponieważ nie ma wbudowanego modułu o nazwie 'yaml' i więcej niż jednej trzeciej biblioteki o tej nazwie, problem może polegać na tym, że używasz innej biblioteki niż ta z odpowiedzi. Sprawdziłem, że PyYAML 3.10, zarówno w czystym Pythonie z libyaml 0.1.4, daje odpowiedzi @JonClements pokazuje, podobnie jak simpleyaml 3.10. Może masz zepsutą bibliotekę (co może również tłumaczyć, dlaczego próbujesz najpierw parsować uszkodzony plik Yaml?). – abarnert

2

Dodatkowy błąd w kodzie, że nie mają do czynienia z YAML:

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

in jest operatorem, który działa na sequence types, a także na mapach. Dlatego nie jest to błąd składni ... ale nie robi to, co chcesz.

key in dict zawsze oceni jako True, ponieważ wszystkie klucze, które przechodzisz, znajdują się w dyktafonie. Twój kod sprowadza się zatem do True == "instanceId", która zawsze będzie oznaczać False, ponieważ wartość boolowska True nigdy nie jest równa temu łańcuchowi znaków.

Być może zauważyłeś, że instrukcja print nie generuje żadnych wyników; to dlatego, że nigdy nie zostaje wywołana.