2012-10-22 9 views
8

Tôi đang gặp sự cố sau khi ánh xạ tài liệu trong tệp YAML đến một số dict và ánh xạ chúng một cách chính xác.Chuyển đổi tệp YAML thành python dict

Tôi có file YAML sau, đại diện cho một máy chủ (db.yml):

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

Tôi tải file YAML này, mà tôi có thể làm mà không có bất kỳ vấn đề, tôi nghĩ tôi hiểu điều đó.

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] 

Tôi muốn logic để làm việc như sau: yaml

  • tải, bản đồ để dict
  • nhìn trong mọi dict trong tài liệu, nếu instanceId trận đấu đó đã được thiết lập bởi getInstanceId(), sau đó in ra tất cả các khóa và giá trị cho tài liệu đó.

Nếu tôi nhìn vào cấu trúc dữ liệu bản đồ từ dòng lệnh, tôi nhận được:

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

Tôi nghĩ rằng tôi có thể tạo ra các cấu trúc dữ liệu cho các file YAML không đúng cách, và trên phù hợp với các nội dung trên các dict, tôi là một chút bị mất.

Lưu ý phụ: Tôi không thể tải tất cả tài liệu trong tệp này bằng cách sử dụng yaml.load(), tôi đã thử yaml.load_all(), có vẻ như hoạt động nhưng vấn đề chính của tôi vẫn tồn tại.

+3

Vui lòng đổi tên 'dict' thành một thứ khác. Đó là xấu xấu.Ngoài ra, bạn có thể in giá trị 'yaml.load_all (luồng)' để chúng ta có thể thấy những gì bạn thực sự có không? Cuối cùng, có vẻ như bạn chưa bao gồm một mẫu YAML tốt - nhiều máy chủ được xác định ở đâu? – gahooa

+0

Tôi sẽ đổi tên nó, cảm ơn bạn đã thực hành tốt nhất. yaml_load_all (luồng) hiển thị: . Tôi đã xóa tài liệu thứ hai để khắc phục sự cố. –

+0

Thư viện/mô-đun nào được sử dụng trong mã? Tôi nghĩ rằng nó sẽ cải thiện câu hỏi này để thêm câu lệnh nhập khẩu, để những người tìm thấy câu hỏi này không phải tìm kiếm nó và có khả năng tìm thấy nhiều câu hỏi có thể. – Zelphir

Trả lời

13

Tôi nghĩ rằng tập tin yaml của bạn sẽ trông như thế (hoặc ít nhất là một cái gì đó như thế nào, vì vậy nó có cấu trúc một cách chính xác anyway):

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

Sau đó, yaml.load(...) lợi nhuận:

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

Và bạn có thể đi từ đó ...


Vì vậy, được sử dụng như:

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

Rất tiếc, tôi đã thử cách này nhưng tôi không nhận được kết quả tương tự bằng cách sử dụng yaml mà bạn đã sử dụng ở trên: https://gist.github.com/3934903 –

+0

@zippy Tệp yaml này đến từ đâu? –

+0

Vì không có mô-đun tích hợp có tên 'yaml' và nhiều thư viện của bên thứ ba có tên đó, vấn đề có thể là bạn đang sử dụng thư viện khác với thư viện từ câu trả lời. Tôi đã xác minh rằng PyYAML 3.10, cả thuần-Python với libyaml 0.1.4, cung cấp câu trả lời @JonClements cho thấy, và vì thế simpleyaml 3.10. Có lẽ bạn có một thư viện bị hỏng (mà cũng có thể giải thích tại sao bạn đang cố gắng phân tích cú pháp yaml bị hỏng ở nơi đầu tiên?). – abarnert

2

Một lỗi bổ sung trong mã của bạn, điều đó không có để làm với YAML:

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

in là một nhà điều hành hoạt động trên sequence types, và cũng có trên bản đồ. Đây là lý do tại sao đây không phải là lỗi cú pháp ... nhưng nó không làm những gì bạn muốn.

key in dict sẽ luôn đánh giá là True, bởi vì tất cả các khóa bạn đang lặp lại đều ở trong chế độ dict. Vì vậy, mã của bạn sẽ chuyển thành True == "instanceId", mã này sẽ luôn luôn đánh giá là False, bởi vì giá trị boolean True không bao giờ bằng với chuỗi đó.

Bạn có thể nhận thấy rằng câu lệnh print không tạo ra bất kỳ đầu ra nào; điều này là bởi vì nó không bao giờ được gọi.