我有一个小脚本,它从表中读取一些行并输出一些嵌套的JSON。问题在于,由于Python是通过引用传递的,所以每次更新临时变量时,我构建的JSON对象都会发生变化。以下是我正在采取的措施:
rows.py
rows = [
['1,', '\\WIN-2N5E8Q63188', 'Memory > Available MBytes', ''],
['2,', '\\WIN-2N5E8Q63188', 'Physical Disk > Avg. Disk sec/Write', '0 C:'],
['3,', '\\WIN-2N5E8Q63188', 'Physical Disk > Avg. Disk sec/Write', '1 F:'],
['4,', '\\WIN-2N5E8Q63188', 'Physical Disk > Avg. Disk sec/Read', '0 C:'],
['5,', '\\WIN-2N5E8Q63188', 'Physical Disk > Avg. Disk sec/Read', '1 F:'],
['6,', '\\WIN-2N5E8Q63188', 'Processor > % Processor Time', '_Total'],
['7,', '\\WIN-2N5E8Q63188', 'Processor > % Privileged Time', '_Total'],
['8,', '\\WIN-2N5E8Q63187', 'Memory > Available MBytes', '']
]
create_json.py
from rows import rows
machine_template = {
'machineName': '',
'counters': []
}
counter_template = {
'counterName': '',
'instances': []
}
instance_template = {
'instanceName': '',
'counterId': -1
}
counter_ids = []
machines = []
counters = []
instances = []
current_machine = ''
current_counter = ''
last_machine = ''
last_counter = ''
current_template = []
data = {'machines': []}
for i in rows:
counter_ids.append(i[0])
machines.append(i[1])
counters.append(i[2])
instances.append(i[3])
row_count = len(counter_ids)
i = 0
while i < row_count:
ct = []
mt = []
new_machine = False
new_counter = False
# handle the instance
it = instance_template
it['instanceName'] = instances[i]
it['counterId'] = counter_ids[i]
# handle the counter
current_counter = counters[i]
if current_counter != last_counter:
new_counter = True
ct = counter_template
ct['counterName'] = counters[i]
# handle the machine name
current_machine = machines[i]
if current_machine != last_machine:
new_machine = True
mt = machine_template
mt['machineName'] = current_machine
# build the template
if new_counter:
ct['instances'].append(it)
if new_machine:
mt['counters'].append(ct)
data['machines'].append(mt)
last_counter = current_counter
last_machine = current_machine
i += 1
print data
以下是成品的外观(不完全针对rows.py文件中提供的数据,但结构相同):
{
"machines":[
{
"machineName": "\\WIN-2N5E8Q63188",
"counters": [
{
"counterName": "MemoryAvailable MBytes",
"instances": [
{
"instanceName": "",
"counterId": 1
}
]
},
{
"counterName": "PhysicalDiskAvg. Disk sec/Write",
"instances": [
{
"instanceName": "0 C:",
"counterId": 2
},
{
"instanceName": "1 F:",
"counterId": 3
}
]
}
]
}
]
}
以下是从我的剧本中返回的内容:
{
'machines': [
{
'machineName': '\\WIN-2N5E8Q63187',
'counters': [
{
'instances': [
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
}
],
'counterName': 'Memory>AvailableMBytes'
},
{
'instances': [
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
}
],
'counterName': 'Memory>AvailableMBytes'
}
]
},
{
'machineName': '\\WIN-2N5E8Q63187',
'counters': [
{
'instances': [
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
}
],
'counterName': 'Memory>AvailableMBytes'
},
{
'instances': [
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
},
{
'counterId': '8,
',
'instanceName': ''
}
],
'counterName': 'Memory>AvailableMBytes'
}
]
}
]
}
关于如何使这项工作的任何想法?
答案 0 :(得分:1)
您需要复制模板以及可能要重复使用的其他列表,但由于模板本身包含空列表,因此浅层副本(dict.copy()
)是不够的。使用deepcopy
模块中的copy
:
from copy import deepcopy
... later ...
# handle the instance
it = deepcopy(instance_template)
it['instanceName'] = instances[i]
it['counterId'] = counter_ids[i]
# handle the counter
current_counter = counters[i]
if current_counter != last_counter:
new_counter = True
ct = deepcopy(counter_template)
ct['counterName'] = counters[i]
# handle the machine name
current_machine = machines[i]
if current_machine != last_machine:
new_machine = True
mt = deepcopy(machine_template)
mt['machineName'] = current_machine
这将使原始模板保持不变,并且可以安全重复使用。
您可能还会发现pprint
模块有助于打印dicts:
from pprint import pprint
pprint(data)
结果:
{'machines': [{'counters': [{'counterName': 'Memory > Available MBytes',
'instances': [{'counterId': '1,',
'instanceName': ''}]}],
'machineName': '\\WIN-2N5E8Q63188'},
{'counters': [{'counterName': 'Memory > Available MBytes',
'instances': [{'counterId': '8,',
'instanceName': ''}]}],
'machineName': '\\WIN-2N5E8Q63187'}]}
就像我说的那样,你可能还需要复制任何被重用的列表 - 如果没有更好地理解你的代码,这个输出是否正确就有点难以理解。