绕过python传递参考

时间:2014-05-15 03:51:01

标签: python json

我有一个小脚本,它从表中读取一些行并输出一些嵌套的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'
                }
            ]
        }
    ]
}

关于如何使这项工作的任何想法?

1 个答案:

答案 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'}]}

就像我说的那样,你可能还需要复制任何被重用的列表 - 如果没有更好地理解你的代码,这个输出是否正确就有点难以理解。