如何对比YAML中多个Memservers配置并修复遍历解包报错
报错根因
触发ValueError: too many values to unpack (expected 2)的直接原因是遍历对象错误:
- 加载YAML后得到的
data是整个配置文件的根级字典,包含provider、ATL_threads、Memservers等顶级键,直接遍历data.values()拿到的是顶级键对应的各类值(字符串、数字、字典等),并非需要校验的内存服务器配置键值对,自然无法解包为machine, config两个变量。 - 原代码还存在拼写错误、校验逻辑偏离需求、变量作用域异常等额外问题,即使修复遍历错误也无法正确实现校验规则。
修正步骤
- 调整遍历目标:所有内存服务器配置都存储在
data['Memservers']字段下,遍历该字典的.items()即可正确拿到(机器ID, 配置项)二元组,解决解包报错。 - 修正拼写错误:将笔误的
con['rpc_interface']改为config['rpc_interface'],补全libfabric_port的正确拼写。 - 重构校验逻辑:不再无差别统计所有重复的
fam_path、libfabric_port,仅针对出现重复的rpc_interface条目,校验其关联的fam_path、libfabric_port是否完全一致,匹配三条校验规则要求。 - 修复变量作用域问题:将重复配置的判断、校验逻辑全部放在同一个遍历流程内,避免循环外调用未定义变量的报错。
修正后完整代码
import sys from pathlib import Path import ruamel.yaml def compare(): # 存储rpc_interface关联配置:key为rpc_interface值,value为(机器id集合, fam_path集合, libfabric_port集合) rpc_config_map = {} file_in = Path(r'C:\Users\User\OneDrive\Desktop\toold\fam_memoryserver_config.yaml') yaml = ruamel.yaml.YAML(typ='safe') data = yaml.load(file_in) # 正确遍历Memservers下的所有服务器配置 for machine_id, config in data['Memservers'].items(): # 先检查必填字段是否存在 required_fields = ['rpc_interface', 'fam_path', 'libfabric_port'] for field in required_fields: if field not in config: print(f'机器 {machine_id} 缺少必填配置项 "{field}"') sys.exit(1) rpc_val = config['rpc_interface'] # 初始化存储结构 if rpc_val not in rpc_config_map: rpc_config_map[rpc_val] = (set(), set(), set()) # 存入当前机器的配置 rpc_config_map[rpc_val][0].add(machine_id) rpc_config_map[rpc_val][1].add(config['fam_path']) rpc_config_map[rpc_val][2].add(config['libfabric_port']) # 执行规则校验 has_duplicate_rpc = False for rpc_val, (machine_set, fam_path_set, port_set) in rpc_config_map.items(): if len(machine_set) == 1: # 无重复rpc_interface,跳过 continue # 命中规则1:存在重复rpc_interface has_duplicate_rpc = True machine_list = [str(x) for x in machine_set] print(f'检测到重复的rpc_interface配置 [{rpc_val}],关联机器:{", ".join(machine_list)}') # 命中规则2:检查fam_path是否一致 if len(fam_path_set) > 1: print(f' 校验失败:上述重复rpc_interface对应的fam_path配置不一致,存在值:{list(fam_path_set)}') else: print(f' 校验通过:重复rpc_interface对应的fam_path配置一致,值为:{fam_path_set.pop()}') # 命中规则3:检查libfabric_port是否一致 if len(port_set) > 1: print(f' 校验失败:上述重复rpc_interface对应的libfabric_port配置不一致,存在值:{list(port_set)}') else: print(f' 校验通过:重复rpc_interface对应的libfabric_port配置一致,值为:{port_set.pop()}') if not has_duplicate_rpc: print('校验通过:未检测到重复的rpc_interface配置') compare()
示例YAML运行结果
你提供的示例配置中三个Memserver的rpc_interface分别为fam5:8793、fam4:8793、fam3:8793,无重复值,运行后输出:
校验通过:未检测到重复的rpc_interface配置
内容的提问来源于stack exchange,提问作者Vsdm in
相关产品推荐
相关产品推荐

