我正在使用一个不幸的系统;使用具有相同键名的嵌套json对象。基于一些基于0到n个元素的输入数据,我需要动态创建这个对象,但不确定如何正确地使用python。
这是我的json在这个例子中看起来像有3个表达式..
{
"metricExpressionTemplate": {
"metricExpressionType": "Boolean",
"operator": {
"type": "PLUS"
},
"expression1": {
"metricExpressionType": "Boolean",
"operator": {
"type": "PLUS"
},
"expression1": {
"metricExpressionType": "Boolean",
"operator": {
"type": "PLUS"
},
"expression1": {
"metricExpressionType": "Boolean",
"operator": {
"type": "PLUS"
}
}
}
}
}
}
我一直试图动态创建它,但即使我尝试手动添加它..
import json
expression_object = {}
template_object = {
"metricExpressionType": "Boolean",
"operator": {
"type": "PLUS"
},
}
expression_object["metricExpressionTemplate"]["expression1"] = template_object
expression_object["metricExpressionTemplate"]["expression1"]["expression1"] = template_object
print(json.dumps(expression_object))
我收到错误消息“ValueError:检测到循环引用”。
现在,即使这确实有效,也可以想象必须为250个物体做这个!在某些类型的for循环..
for i in range(0,200):
# Add Expression objects dynamically..
expression_object["metricExpressionType"]["expression1"] = template_object
我所知道的dict对象上没有“get_json_root”或“append”方法。我该怎么办呢?
答案 0 :(得分:1)
不是将template_object
分配给["metricExpressionTemplate"]["expression1"]
和["metricExpressionTemplate"]["expression1"]["expression1"]
,而是每次都使用工厂方法生成新的模板对象。所以:
import json
def newTemplateObject():
t = {
"metricExpressionType": "Boolean",
"operator": {
"type": "PLUS"
},
}
return t
expression_object = {}
expression_object["metricExpressionTemplate"] = newTemplateObject()
expression_object["metricExpressionTemplate"]["expression1"] = newTemplateObject()
expression_object["metricExpressionTemplate"]["expression1"]["expression1"] = newTemplateObject()
print(json.dumps(expression_object))
对于有深度未知的对象时添加template_object,可以使用递归方法,每次调用都会检查传递给它的对象是否有一个键" expression1":
def addExpression(obj):
if "expression1" in obj.keys():
addExpression(obj["expression1"])
else:
obj["expression1"] = newTemplateObject()
答案 1 :(得分:0)
发生错误是因为您试图在自身内部重用相同的对象。这可以通过每次需要时生成新字典来克服。然后,这可以通过递归系统循环执行,例如:
import json
def get_contents():
return {
"metricExpressionType": "Boolean",
"operator": {
"type": "PLUS"
}
}
def add_contents(d, contents, remaining):
d['expression1'] = contents()
if remaining > 0:
add_contents(d['expression1'], contents, remaining - 1)
objects = []
templates = ['metricExpressionTemplate', 'b', 'c']
for template_name in templates:
d = {template_name: get_contents()}
add_contents(d, get_contents, 2)
objects.append(d)
print json.dumps(objects, indent=2)