我在下面有一个python脚本,它会加载一个yaml文件。参数作为列表传入,因此我可以遍历它们以向字典添加值。下面的代码添加了参数,但json没有正确格式化,如当前和所需的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"
}
]
}
]
}
]
}
答案 0 :(得分: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
会为该字典添加新的key:value对:
{
"State.Name": "running",
"tag:BUSINESS_UNIT": "TEST_FLITE"
}
循环没有帮助,它在每个迭代步骤中都是一样的。
我的提议会将所需的键:值对作为字典附加到列表的末尾。如果订单真的很重要,那么你必须改变清单。看看模块collections.deque
。
答案 1 :(得分: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))