【发布时间】:2021-12-30 23:58:08
【问题描述】:
我正在使用 Python zeep 发出 SOAP 请求。据我所知,zeep 可以使用字典作为输入来提出请求。
由于我正在使用多种方法,因此我想创建一个通用函数来接收参数及其在方法的 WSDL 中定义的相应层次结构,并构造 request_data_dictionary,考虑到它可能包含嵌套数据,它可能非常复杂。
在定义我的参数时,我给了他们一个级别属性,以了解该参数在请求数据字典中的深度。而且我确信参数是按顺序处理的。
我的测试用例具有以下结构。我有 4 个参数:par1、par2、par3 和 par4。每个参数都是编号较小的参数的子参数,因此 par2 是 par1 的子参数,依此类推。我需要的数据输出形式如下:
{'par0': {'par1': {'par2': {'par3': {'par4': False}}}}}
如果我添加一个 par2.1 作为 par1 的另一个孩子,字典应该有这种形式:
{'par0': {'par1': {'par2.1': False, 'par2': {'par3': {'par4': False}}}}}
所以我编写了以下函数来构造我的 request_dictionary:
def _prepare_request_dictionary(self):
data_dictionary = {}
for line in self.request_line_ids.sorted(key=lambda l: l.parameter_id.level):
parameter_name = line.parameter_id.name
parent_parameter_name = line.parameter_id.parent_id.name if line.parameter_id.parent_id else False
line_value = convert_value(line.value, line.parameter_type) if not line.parameter_id.is_compound and line.value else False
if line.parameter_id.level == 1 and parameter_name not in data_dictionary.keys():
data_dictionary[parameter_name] = line_value
elif line.parameter_id.level == 2:
if parent_parameter_name in data_dictionary.keys():
data_dictionary = if isinstance(data_dictionary[parent_parameter_name], dict):
data_dictionary[parent_parameter_name] = {**data_dictionary[parent_parameter_name], **{parameter_name: line_value}}
elif isinstance(data_dictionary[parent_parameter_name], list):
data_dictionary[parent_parameter_name].append({parameter_name: line_value})
elif data_dictionary[parent_parameter_name] is False:
data_dictionary[parent_parameter_name] = {parameter_name: line_value}
elif line.parameter_id.level == 3:
for value in data_dictionary.values():
if isinstance(value, dict):
if parent_parameter_name in value.keys():
if isinstance(value[parent_parameter_name], dict):
value[parent_parameter_name] = {**value[parent_parameter_name], **{parameter_name: line_value}}
elif isinstance(value[parent_parameter_name], list):
value[parent_parameter_name].append({parameter_name: line_value})
elif value[parent_parameter_name] is False:
value[parent_parameter_name] = {parameter_name: line_value}
elif line.parameter_id.level == 4:
for value in data_dictionary.values():
if isinstance(value, dict):
for sub_value in value.values():
if parent_parameter_name in sub_value.keys():
if isinstance(sub_value[parent_parameter_name], dict):
sub_value[parent_parameter_name] = {**sub_value[parent_parameter_name], **{parameter_name: line_value}}
elif isinstance(sub_value[parent_parameter_name], list):
sub_value[parent_parameter_name].append({parameter_name: line_value})
elif sub_value[parent_parameter_name] is False:
sub_value[parent_parameter_name] = {parameter_name: line_value}
elif line.parameter_id.level == 5:
for value in data_dictionary.values():
if isinstance(value, dict):
for sub_value in value.values():
if isinstance(sub_value, dict):
for sub_sub_value in sub_value.values():
if isinstance(sub_sub_value, dict):
if parent_parameter_name in sub_sub_value.keys():
if isinstance(sub_sub_value[parent_parameter_name], dict):
sub_sub_value[parent_parameter_name] = {**sub_sub_value[parent_parameter_name], **{parameter_name: line_value}}
elif isinstance(sub_sub_value[parent_parameter_name], list):
sub_sub_value[parent_parameter_name].append({parameter_name: line_value})
elif sub_sub_value[parent_parameter_name] is False:
sub_sub_value[parent_parameter_name] = {parameter_name: line_value}
return data_dictionary
如你所见,这个函数有一些重复的部分,如下所示:
if isinstance(value[parent_parameter_name], dict):
value[parent_parameter_name] = {**value[parent_parameter_name], **{parameter_name: line_value}}
elif isinstance(value[parent_parameter_name], list):
value[parent_parameter_name].append({parameter_name: line_value})
elif value[parent_parameter_name] is False:
value[parent_parameter_name] = {parameter_name: line_value}
还有这个:
for value in data_dictionary.values():
if isinstance(value, dict):
for sub_value in value.values():
if isinstance(sub_value, dict):
for sub_sub_value in sub_value.values():
if isinstance(sub_sub_value, dict):
所以我做了一个名为“update_data_dictionary”的子函数来模块化它:
def update_data_dictionary(work_dictionary, update_dictionary, parent_parameter):
if isinstance(work_dictionary[parent_parameter], dict):
work_dictionary[parent_parameter] = {**work_dictionary[parent_parameter], **update_dictionary}
elif isinstance(work_dictionary[parent_parameter], list):
work_dictionary[parent_parameter].append(update_dictionary)
elif work_dictionary[parent_parameter] is False:
work_dictionary[parent_parameter] = update_dictionary
return work_dictionary
问题是我不知道如何在第 3 级再次使用此方法,因为函数“update_data_dictionary”返回一个无法替换值的字典。
我知道这可以通过递归函数来解决,如果有人可以帮助我将这个递归函数变成一个无限级别的递归函数,我将不胜感激。
【问题讨论】:
-
你能给出一个数据例子和一个你想要构建的具有理想结构的字典的例子吗?目前很难理解你的代码做了什么以及你想要实现什么。
-
嗨,我编辑以更好地解释我想要的字典应该如何输出。我没有提到的是我正在使用 Odoo 并且 request_line_ids 变量是我使用参数创建的模型的记录集。
标签: python python-3.x dictionary recursion