循环调用函数报TypeError: 'NoneType' object is not subscriptable如何解决
错误原因
- 报错的核心是
read_digital_input.main("i1", adams_ips[n])返回了None值,你直接对None执行[0]索引操作触发类型错误。 - 返回None的具体原因:
read_digital_input.py中的main函数异常捕获逻辑不完整:仅捕获了ValueError,网络不通、Modbus设备离线、连接超时、读取失败等场景都不会触发该异常,且pyModbusTCP的read_coils方法在读取失败时会直接返回None而非抛出异常,函数会把这个None直接返回。- 就算触发了
ValueError进入except分支,该分支仅打印日志,没有任何return语句,函数默认返回None。 - 之前其他场景未报错是因为之前设备网络稳定、读取成功率高,本次循环长时间高频调用,一旦出现设备响应超时/离线就会触发返回None的情况。
解决方案
分两步修改即可解决:
第一步:修改read_digital_input.py的逻辑,增加有效性判断和异常兼容
import time from pyModbusTCP.client import ModbusClient port = 502 # 端口改为整数类型,避免ModbusClient参数适配问题 coil_dictionary = { "i0": 0, "i1": 1, "i2": 2, "i3": 3, "i4": 4 } def main(coil, host, retry=3): print(host) # 增加重试机制,避免偶发网络波动导致失败 for _ in range(retry): try: c = ModbusClient(host, port, timeout=2) # 增加超时时间,避免长时间卡住 if not c.open(): print(f"连接设备{host}失败,重试中...") time.sleep(0.2) continue state = c.read_coils(coil_dictionary[coil]) c.close() # 用完主动关闭连接,避免连接数堆积 if state is not None: return state print(f"读取设备{host}线圈失败,重试中...") time.sleep(0.2) except Exception as e: # 捕获所有可能的异常,避免无返回值 print(f"操作设备{host}出错:{str(e)},重试中...") time.sleep(0.2) # 重试多次都失败返回None,留给上层逻辑处理 print(f"设备{host}多次操作失败") return None
第二步:修改主脚本调用逻辑,增加返回值判断,避免直接索引None
找到主脚本中报错的行,替换为如下逻辑:
# 原代码:alarmStatus = read_digital_input.main("i1", adams_ips[n])[0] # 替换为: res = read_digital_input.main("i1", adams_ips[n]) if res is None: # 读取失败跳过本次循环,等待下一轮再尝试 print(f"读取设备{n}状态失败,跳过本次处理") time.sleep(0.5) continue alarmStatus = res[0]
内容的提问来源于stack exchange,提问作者pbdiazam
相关产品推荐
相关产品推荐

