2017-09-04 69 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