如何优雅检查并补充字典中缺失的API数据字段?
问题与解决方案
问题描述
从API拉取数据并输出为Influx Line格式时,API不会返回null值,而是直接省略缺失的字段,导致Python代码触发KeyError报错。
报错代码片段
for serial in SERIALS[site]: r = requests.get(f"{BASE_API_URL}/equipment/{site}/{serial}/data", { 'startTime': format_datetime_url(startTime), 'endTime': format_datetime_url(endTime), 'api_key': SETTING_API_KEY }, timeout=REQUEST_TIMEOUT) # Parse request for value in r.json()['data']['telemetries']: date = value['date'] print( f'data,site={site},sn={serial} I_Temp={value["temperature"]},I_AC_Energy_WH={value["totalEnergy"]},I_AC_Power={value["totalActivePower"]} {to_unix_timestamp(date)}', flush=False) return True
当前临时处理方式
通过逐个判断字段是否存在,给缺失字段赋值空字符串:
if not 'temperature' in value: value["temperature"] = "" if not 'totalEnergy' in value: value["totalEnergy"] = "" if not 'totalActivePower' in value: value["totalActivePower"] = ""
想寻求更优雅的实现方式。
更优雅的实现方式
方法1:使用字典get()方法(推荐)
Python字典的get()方法支持指定默认值,当键不存在时直接返回预设的默认值,无需提前修改原字典,代码更简洁:
for value in r.json()['data']['telemetries']: date = value['date'] # 直接通过get()取值,缺失时返回空字符串 temp = value.get('temperature', '') total_energy = value.get('totalEnergy', '') total_power = value.get('totalActivePower', '') print( f'data,site={site},sn={serial} I_Temp={temp},I_AC_Energy_WH={total_energy},I_AC_Power={total_power} {to_unix_timestamp(date)}', flush=False)
方法2:字段映射批量处理(适合字段较多的场景)
如果后续需要新增字段,可通过定义字段映射表批量处理,避免重复编写get()逻辑,扩展性更强:
# 定义Influx字段名与API返回字段名的映射关系 field_map = { 'I_Temp': 'temperature', 'I_AC_Energy_WH': 'totalEnergy', 'I_AC_Power': 'totalActivePower' } for value in r.json()['data']['telemetries']: date = value['date'] # 批量生成Influx格式的字段键值对 field_parts = [f"{influx_key}={value.get(api_key, '')}" for influx_key, api_key in field_map.items()] # 拼接成完整的Influx Line字符串 line_str = f'data,site={site},sn={serial} {",".join(field_parts)} {to_unix_timestamp(date)}' print(line_str, flush=False)
后续新增字段时,只需在field_map中添加对应关系即可,无需改动循环内的代码。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

