2017-07-17 29 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'模块。 –