2014-05-15 51 views
0

我有一個小的腳本,從表中讀取一些行並輸出一些嵌套的JSON。問題是,由於Python是通過引用傳遞的,所以每次我更新我的臨時變量時,我正在構建的JSON對象都會發生變化。這就是我要帶約:解決python通過引用

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 

這裏的成品應該是什麼樣子(不完全爲行中提供的數據.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

它似乎不像模板字典爲你做了很多。如何每次創建一個新字典? –

+0

如何使用cPickle爲您輸出JSON? – 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 

這將使原始模板不變和安全的重用。

您也可能會發現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'}]} 

就像我說的,你可能還需要複製得到重用任何名單 - 這是一個很難判斷這個輸出是否正確,但不能更好地理解你的代碼。