2017-09-04 72 views
0

我有一個python腳本下面加載yaml文件。參數以列表的形式傳入,因此我可以通過循環來向字典中添加值。下面的代碼添加了參數,但是json格式不正確,顯示在當前和期望的json結果中。任何幫助正確的方向表示讚賞。謝謝。python字符串到json轉換

YAML文件

policies: 
    - name: ec2age 
    resource: ec2 
    filters:  
     - State.Name: running 
     - "tag:ResourceCreatedBy": present 
     - and: 
     - type: instance-age 
      days: 30 
      op: ge 

Python腳本:

#!/usr/bin/python 
import sys 
import argparse 
import json 
import yaml 

parser = argparse.ArgumentParser() 
parser.add_argument("-y", "--yaml_file", type=str) 
parser.add_argument("-b", "--business_unit", type=str) 
parser.add_argument("-p", "--platform", type=str) 
parser.add_argument("-c", "--client", type=str) 
args = parser.parse_args() 

with open(args.yaml_file, 'r') as stream: 
    data = yaml.load(stream) 

inner_dict = [args.business_unit, args.platform, args.client] 

for item in list(inner_dict): 
    data['policies'][0]['filters'][0]['tag:BUSINESS_UNIT'] = args.business_unit 
    data['policies'][0]['filters'][1]['tag:PLATFORM'] = args.platform 

print json.dumps(data) 

當前結果:

{ 
"policies": [ 
    { 
    "resource": "ec2", 
    "name": "ec2age", 
    "filters": [ 
     { 
     "tag:BUSINESS_UNIT": "TEST_FLITE", 
     "State.Name": "running" 
     }, 
     { 
     "tag:ResourceCreatedBy": "present" 
     }, 
     { 
     "and": [ 
      { 
      "type": "instance-age", 
      "days": 30, 
      "op": "ge" 
      } 
     ] 
     } 
    ] 
    } 
] 
} 

所需的結果:

{ 
"policies": [ 
    { 
    "resource": "ec2", 
    "name": "ec2age", 
    "filters": [ 
     { 
     "tag:BUSINESS_UNIT": "TEST_FLITE" 
     }, 
     { 
     "tag:PLATFORM": "Android" 
     }, 
     {    
     "State.Name": "running" 
     }, 
     { 
     "tag:ResourceCreatedBy": "present" 
     }, 
     { 
     "and": [ 
      { 
      "type": "instance-age", 
      "days": 30, 
      "op": "ge" 
      } 
     ] 
     } 
    ] 
    } 
] 
} 
+1

它可以isssue與YAML,不看YAML似乎很難說。 您可以驗證YAML中的選項卡,是否通過打印字典/數據本身進行驗證? –

回答

1

在你的代碼,

inner_dict = [args.business_unit, args.platform, args.client] 

for item in list(inner_dict): 
    """ 
     following line appends adds key to 0'th dict which is 
    { 
    "tag:BUSINESS_UNIT": "TEST_FLITE", 
    "State.Name": "running" 
    } 
    """ 
    data['policies'][0]['filters'][0]['tag:BUSINESS_UNIT'] = args.business_unit 
    data['policies'][0]['filters'][1]['tag:PLATFORM'] = args.platform 

你可以做這樣的事情,

#!/usr/bin/python 

from __future__ import print_function 
import sys 
import argparse 
import json 
import yaml 

parser = argparse.ArgumentParser() 
parser.add_argument("-y", "--yaml_file", type=str) 
parser.add_argument("-b", "--business_unit", type=str) 
parser.add_argument("-p", "--platform", type=str) 
parser.add_argument("-c", "--client", type=str) 
args = parser.parse_args() 

with open(args.yaml_file, 'r') as stream: 
    data = yaml.load(stream) 


inner_list = [{"tag:BUSINESS_UNIT" : args.business_unit}, 
       {"tag:PLATFORM" : args.platform}, 
       # {"tag:CLIENT" : args.client} #if needed 
      ] 

for i, item in enumerate(inner_list): 
    data['policies'][0]['filters'].insert(i, item) 

print(json.dumps(data)) 
+1

用'insert'好主意!然而,OP沒有提及任何關於'{「標籤:PLATFORM」:args.client}'的內容。但如果需要,他/她應該決定如何調用該密鑰。 – cezar

+0

感謝這工作!欣賞迴應。 – kilomo

1

你的這部分代碼:

inner_dict = [args.business_unit, args.platform, args.client] 

for item in list(inner_dict): 
    data['policies'][0]['filters'][0]['tag:BUSINESS_UNIT'] = args.business_unit 
    data['policies'][0]['filters'][1]['tag:PLATFORM'] = args.platform 

並沒有真正有很大的意義。首先,inner_dict已經是一個列表。沒有理由我們將其轉換爲列表 - list(inner_dict)

其次,在循環中迭代3次,爲列表中的每個項目重複一次,並在每個迭代步驟中重複相同的語句。這些陳述中不使用item

從這裏,不知道YAML文件的結構,很難提供一個解決方案,但你應該尋找上述線。我想嘗試不循環,只需要執行:

data['policies'][0]['filters'].append({'tag:BUSINESS_UNIT': args.business_unit}) 
data['policies'][0]['filters'].append({'tag:PLATFORM': args.platform}) 

編輯:您添加的YAML文件內容,我可以給你一個進一步的解釋後。 當你調用data['policies'][0]['filters']調用此部分:

[ 
    {    
     "State.Name": "running" 
    }, 
    { 
     "tag:ResourceCreatedBy": "present" 
    }, 
    { 
     "and": [ 
      { 
       "type": "instance-age", 
       "days": 30, 
       "op": "ge" 
      } 
     ] 
    } 
] 

因此data['policies'][0]['filters'][0]將返回:

{    
    "State.Name": "running" 
} 

data['policies'][0]['filters'][0]['tag:BUSINESS_UNIT'] = args.business_unit將新的密鑰添加:值對到字典:

{    
    "State.Name": "running", 
    "tag:BUSINESS_UNIT": "TEST_FLITE" 
} 

的循環不起作用,它在每個迭代步驟中都會執行相同的操作。

我的建議會將所需的鍵值對添加爲列表末尾的字典。如果訂單真的很重要,那麼你必須改變名單。看看模塊collections.deque

+0

感謝您的回覆。我添加了yaml文件內容。 – kilomo