2014-05-15 2 views
0

테이블에서 일부 행을 읽고 중첩 된 JSON을 출력하는 작은 스크립트가 있습니다. 문제는 Python이 참조로 전달되기 때문에 임시 변수를 업데이트 할 때마다 건물의 JSON 객체가 변경된다는 것입니다. 여기에 대해 취하고있는 작업은 다음과 같습니다참조로 전달되는 python 둘러보기

rows.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 = [ 
    ['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 정확히 행에 제공되는 데이터에 대한 .py 파일이지만 같은 구조 임) :

내 스크립트에서 반환되는 내용은 다음과 같습니다.

{ 
    '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

템플릿 사전이 당신을 위해 많은 일을하는 것처럼 보이지 않습니다. 매번 새로운 사전을 만드는 것은 어떨까요? –

+0

JSON을 출력하는 cPickle을 사용하는 것이 어떻습니까? – inspectorG4dget

+1

[dict.copy()] (https://docs.python.org/2/library/stdtypes.html#dict.copy)를 템플릿과 함께 사용해 보았습니까? –

답변

1

템플릿을 복사해야하며 재사용하려는 다른 목록도 필요할 수 있지만 템플릿 자체에는 빈 목록이 포함되어 있으므로 얕은 복사본 (dict.copy())으로는 충분하지 않습니다. copy 모듈에서 deepcopy를 사용하여이 재사용 그대로 안전 원래 템플릿을 떠나

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 

.

또한 인쇄 dicts을 위해 도움이 pprint 모듈을 찾을 수 있습니다

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

- 그것은이다 코드를 더 잘 이해하지 않으면이 출력이 올바른지 알기가 거의 어렵습니다.

관련 문제