2012-10-22 38 views
8

YAMLファイル内のドキュメントをdictにマッピングし、それらを適切にマッピングするという次の問題があります。YAMLファイルをpython dictに変換する

私は、サーバー(db.yml)を表し、次のYAMLファイルを、持っている:私は、私は何の問題もなく行うことができ、このYAMLファイルをロード

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

を、私はそれを理解すると思います。 instanceId一致していることを設定した場合、マップは、文書内のすべての辞書で

  • 見てのdictする

    • 負荷YAML:

      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] 
      

      私は次のように動作するロジックを希望しますgetInstanceId()によって、その文書のすべてのキーと値を印刷します。

    私は、コマンドラインから地図データの構造を見れば、私が取得:

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

    私は不適切YAMLファイルのデータ構造を作成するかもしれないと思う、との内容の一致にdict、私は少し失われています。

    サイドノート:yaml.load()を使用してこのファイルのすべてのドキュメントを読み込むことができませんでしたが、私はyaml.load_all()を試しましたが、私の主な問題は依然として存在しています。

  • +3

    'dict'の名前を変更してください。それは悪い悪いです。また、 'yaml.load_all(stream)'の値を表示して、実際に何があるのか​​を見ることができますか?最後に、あなたが良いYAMLサンプルを含んでいるようには見えません - 複数のサーバがどこに定義されていますか? – gahooa

    +0

    名前を変更します。ベストプラクティスに感謝します。 yaml_load_all(ストリーム)は、<ジェネレータオブジェクトload_all at 0x10b2648c0>を示します。トラブルシューティングのために2番目の文書を削除しました。 –

    +0

    コードにはどのライブラリ/モジュールが使用されていますか?私は、この質問を見つける人がそれを検索する必要はなく、潜在的に複数の可能なものを見つけることができるように、この質問を改善すると思います。 – Zelphir

    答えて

    13

    は、私はあなたのYAMLファイルは次のようになりべきだと思います(のような、あるいは少なくとも何か、それは正しくとにかく構造です):

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

    その後、yaml.load(...)リターン:

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

    そして、あなたがから行くことができます...

    のように使用されます。
    >>> 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

    うーん、私はこれを試しましたが、上記のyamlを使って同じ結果を得られません: https://gist.github.com/3934903 –

    +0

    @zippyこのyamlファイルはどこから来ますか? –

    +0

    'yaml'という名前のモジュールと、その名前を持つ複数のサードパーティ製のライブラリがないので、答えのライブラリとは別のライブラリを使用している可能性があります。私はPyYAML 3.10(純粋なPythonとlibyaml 0.1.4の両方)が@JonClementsの答えを示していることを確認しました。また、simpleyaml 3.10もそうです。たぶんあなたは壊れた図書館を持っているかもしれません(なぜ、あなたが最初に壊れたyamlを解析しようとしているのか説明するかもしれません)。 – abarnert

    2

    YAMLを行う必要はありませんあなたのコードでは、追加のバグ、:

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

    insequence typesに、また、マップ上で動作演算子です。これは構文エラーではありませんが、あなたが望むことはしません。

    key in dictは、反復処理中のすべてのキーがdictにあるため、常にTrueと評価されます。そのため、コードはになります。ブール値Trueはその文字列と決して等しくないため、常にFalseと評価されます。

    printステートメントで出力が生成されないことに気づいたことがあります。これは決して呼ばれないからです。