我想提供以后可以由用户编辑的模板。 因此,它应该是人类可读的.json对象。
仅包含一个字段的模板示例:
{"template_name": "sample_name",
"attribute_fields":
[{"attribute_name": "banana",
"attribute_tags": ["chiquita", "pinkylady"],
"attribute_numbers": [[1, 2, 3, 4] [5, 6, 7, 8]]}]
}
我想动态扩展此json,因为有时会添加更多字段-因此应该有更多的“ attribute_fields”
像这样:
{"template_name": "sample_name",
"attribute_fields":
[{"attribute_name": "banana",
"attribute_tags": ["chiquita", "pinkylady"],
"attribute_numbers": [[1, 2, 3, 4] [5, 6, 7, 8]]},
{attribute_name": "apple",
"attribute_tags": ["applejack", "applepie"],
"attribute_numbers": [[123, 45] [666] [5, 5, 5, 5]]}]
}
到目前为止,我已经通过创建一个空的defaultdict来做到这一点,
empty_template = collections.defaultdict(list)
#yes I used a list.. don't know if there would've been a better option, just tried it and sticked to it
empty_template["template_name"].append(template_name)
looks like this
{"template_name": "sample_name"}
or, printing it, it looks exactly like this:
defaultdict(<class 'list'>, {'template_name': ['sample_name']})
然后创建具有所有所需属性的新defaultdict,然后将此新defaultdict(new_attribute_dict)附加到旧defaultdict(template_to_be_extended)。
def add_attribute_to_template:
new_attribute_dict = create_new_attribute_dict(attribute_name, attribute_tags, attribute_numbers)
template_to_be_extended["attribute_fields"].append(new_attribute_dict)
#create_new_attribute_dict looks like this:
# create empty dictionary
attribute_dict = collections.defaultdict(list)
# add all attribute properties
attribute_dict["attribute_name"] = attribute_name
... and so on
之后,我将这个扩展模板json.dump并将其放入数据库中。到这里为止,一切似乎都还可以(但我真的认为应该有一种更漂亮的方法来实现这一目标?)。
在我用json.loads读回它之后,我必须再次从该json字符串中做出一个defaultdict,以便可以附加键值对(attribute_fields)。这是所有事情变得很糟糕的地方,我不知道该怎么办。我这样尝试:
template_to_be_extended = collections.defaultdict(lambda: json.loads(template_persistence.get(template_name))) #template_persistence returns the file from my database
extended_template = template_creator.add_attribute_to_template(template_to_be_extended,
attribute_name, attribute_tags, attribute_numbers)
但是我真的不知道。会以为我可以再次获得defaultdict,而无需使用lambda,但这会引发错误(TypeError:第一个参数必须可调用或无)-因此我将其设为可调用.. ugh ..
这样,我得到了AttributeError:'dict'对象没有属性'append',所以我也尝试从extended_template中创建一个defaultdict
extended_template = collections.defaultdict(lambda: template_creator.add_attribute_to_template(template_to_be_extended,
attribute_name, attribute_tags, attribute_numbers))
错误消失了,但是打印扩展模板只会返回一个空的{}。
这个问题坚持了几个小时,现在看不到任何东西。也许盯着它太久了。 会对所有提示或其他实现结果的方式感到满意(重要的是我以后可以使用反序列化的json对象中的列表)。
预先感谢
卡尔萨里
答案 0 :(得分:1)
我将自由调整您存储模板的方式,并提出以下(示例)结构:
{
"template1": [
{
"attribute_name": "banana",
"attribute_tags": ["chiquita", "pinkylady"],
"attribute_numbers": [[1, 2, 3, 4], [5, 6, 7, 8]]
},
{
"attribute_name": "apple",
"attribute_tags": ["applejack", "applepie"],
"attribute_numbers": [[123, 45], [666], [5, 5, 5, 5]]
}
],
"template2": [
{
"attribute_name": "fwafaw",
"attribute_tags": ["fawg", "gawggwa"],
"attribute_numbers": [[22]]
},
{
"attribute_name": "vccbx",
"attribute_tags": ["vzvvxz", "wgagaw"],
"attribute_numbers": [[123, 66], [5, 5]]
}
]
}
基本上,您将模板保存在字典中,每个键代表模板名称,其中值是属性列表。
您可以使用pickle
将整个内容作为二进制文件存储在文件中,您可以像以前一样从文件中检索它,从而避免了JSON序列化/反序列化。
示例代码:
import pickle
from collections import defaultdict
# initialize the templates variable
templates = defaultdict(list)
# add the first template
templates['template1'].append({
"attribute_name": "banana",
"attribute_tags": ["chiquita", "pinkylady"],
"attribute_numbers": [[1, 2, 3, 4], [5, 6, 7, 8]]
})
# store the templates data to a binary file
with open("templates.data", "wb") as pf:
pickle.dump(templates, pf)
# retrieve the templates from the binary file
with open("templates.data", "rb") as pf:
retrieved_templates = pickle.load(pf)
# let's inspect the retrieved templates, it will be exactly like the initial structure
print(retrieved_templates)
# let's append a new attribute to the template
retrieved_templates['template1'].append({
"attribute_name": "apple",
"attribute_tags": ["applejack", "applepie"],
"attribute_numbers": [[123, 45], [666], [5, 5, 5, 5]]
})
# restore the templates data
with open("templates.data", "wb") as pf:
pickle.dump(retrieved_templates, pf)
# re-retrieve the templates
with open("templates.data", "rb") as pf:
retrieved_templates_second = pickle.load(pf)
# will display with the updated attributes
print(retrieved_templates_second)
如果要在控制台中运行它,则将具有:
defaultdict(<class 'list'>, {'template1': [{'attribute_name': 'banana', 'attribute_tags': ['chiquita', 'pinkylady'], 'attribute_numbers': [[1, 2, 3, 4], [5, 6, 7, 8]]}]})
然后是
defaultdict(<class 'list'>, {'template1': [{'attribute_name': 'banana', 'attribute_tags': ['chiquita', 'pinkylady'], 'attribute_numbers': [[1, 2, 3, 4], [5, 6, 7, 8]]}, {'attribute_name': 'apple', 'attribute_tags': ['applejack', 'applepie'], 'attribute_numbers': [[123, 45], [666], [5, 5, 5, 5]]}]})
此代码旨在概述您要实现的目标,因此,如果要隐藏这些操作并在函数和类下进行概括,请尝试保持此脚本中提供的流程。