2017-07-17 28 views
1

我的方法接受兩個屬性和一個json列表並返回相應的值。它按預期工作。從變量構建命令通過的參數數

現在,我想添加功能,讓它返回相應的值,而不管它的深度如何。

例如,現在它接受parentchild參數,並返回一個值(請參見下文):return jsonprops[parent][child]

是否可以讓它接受任意數量的參數並返回相應的值? return jsonprops[parent][child1][child2]....[childN]

我發現通過可變數量的args的方法(下圖)的例子,但我不知道如何構建return jsonprops[parent][child],因爲它會有權責令ARGS在[]

期望的解決方案將返回一個值用於return jsonprops[parent][child]以及return jsonprops[parent][child1][child2][child3][child4]

傳遞變量數目args來的方法:

def multipleArgs(*arg): 
    print "Called with", len(arg), "arguments:", arg 

讀JSON文件:

import json 

def read_json(parent, child, jsonprops=[]) 
    return jsonprops[parent][child] 

exampleFile = json.loads(open(example.json).read()) 
childInfo = read_json('parentProps', 'childProp1', exampleFile) 
print childInfo 

例JSON

{ 
    "generalInfo": { 
    "name": "example", 
    "schemaVersion": "1.0", 
    "description": "metadata to be an example" 
    }, 
    "parentProps": { 
     "childProp1": "hi 1", 
     "childProp2": "hi 2", 
     "childProp3": { 
     "newParent": [ 
      { 
      "parent1": [ 
       { 
       "grandChild1": "GC1", 
       "grandChild2": "GC2", 
       "grandChild3": "GC3" 
       }, 
       { 
       "numberofKids": "5", 
       "grandChild4": "GC4", 
       "grandChild5": "GC5", 
       "grandChild6": "GC6" 
       } 
      ], 
      "parent2": [ 
       { 
       "numberofKids": "1", 
       "grandChild11": "GC11", 
       "grandChild12": "GC12", 
       "grandChild13": "GC13" 
       }, 
       { 
       "grandChild14": "GC14", 
       "grandChild15": "GC15", 
       "grandChild16": "GC16" 
       } 
      ] 
      } 
     ] 
     } 
    } 
    } 

回答

0

從任意訪問值數據結構中的深度,你可能想要使用循環。這裏有一個簡單的方法來做到這一點:

def get_value(data, *keys): 
    for key in keys: 
     data = data[key] 
    return data 

您還可以使用由reduce功能(這在Python 3是functools模塊的一部分)進行的隱式循環:

from functools import reduce # this line is only needed in Python 3 
from operator import getitem 

def get_value(*args): # data should be first argument, followed by any number of keys 
    return reduce(getitem, args) 
+0

感謝您的解決方案。我使用Python 2.x.我嘗試了你的方法,但它在'grandChild1'上的錯誤:'File「./jsonTest.py」,第15行,在get_value中 data = data [key] TypeError:列表索引必須是整數,而不是str'。雖然它一直工作到深度3('parentProps','childProps3','newParent')。 –

+0

'newParent'後面的關鍵字需要是一個整數,因爲您的數據結構中有一個列表(請注意,'grandChild'鍵和值分爲兩個字典)。嘗試'get_value(jsonprops,'parentProps','childProp3','newParent',0,'grandChild1')'它應該工作。 – Blckknght

+0

謝謝,它的工作原理。但它不適用於嵌套列表(檢查更新的json文件) –

0

如何使用jsonpathobjectpath模塊:

In [22]: from objectpath import Tree 

In [23]: j = """ 
    ...: { 
    ...: "generalInfo": { 
    ...: "name": "example", 
    ...: "schemaVersion": "1.0", 
    ...: "description": "metadata to be an example" 
    ...: }, 
    ...: "parentProps": { 
    ...:  "childProp1": "hi 1", 
    ...:  "childProp2": "hi 2", 
    ...:  "childProp3": { 
    ...:  "newParent": [ 
    ...:   { 
    ...:   "grandChild1": "GC1", 
    ...:   "grandChild2": "GC2", 
    ...:   "grandChild3": "GC3" 
    ...:   }, 
    ...:   { 
    ...:   "grandChild4": "GC4", 
    ...:   "grandChild5": "GC5", 
    ...:   "grandChild6": "GC6" 
    ...:   } 
    ...:  ] 
    ...:  } 
    ...: } 
    ...: }""" 

In [24]: j = json.loads(j) 

In [25]: next(Tree(j).execute('$..{}..{}'.format('parentProps', 'childProp1'))) 
Out[25]: 'hi 1' 

In [53]: next(Tree(j).execute('$..{}..{}'.format('newParent', 'grandChild5'))) 
Out[53]: 'GC5' 

你的函數,那麼將加載JSON和與objectpath的幫助下返回結果(如果有的話)

+0

我喜歡方法,不幸的是我沒有'objectpath'模塊。 –