5个HC-SR04传感器同步采集时如何无错实现编号递增与对应数据存储
现有代码的报错根源
- 属性引用逻辑错误:代码中写的
self.sensor_i会被Python直接解析为对实例固定属性sensor_i的append操作,如果类初始化时没有提前定义这个属性,会直接触发AttributeError报错,完全达不到动态生成sensor_1、sensor_2这类属性的预期。 - 编号规则错位:原循环用
range(0,5)生成序号,最终输出的传感器编号是HC-SR04.0到HC-SR04.4,和预期的从1开始的逐次递增规则不匹配。 - 存储流程脱节:原代码在循环初始化阶段批量生成传感器对象,没有绑定每次扫描时刻的实时采集数据,无法实现“第1次扫描数据存入sensor_1、第2次存入sensor_2”的映射关系。
调整后可正常运行的实现方案
方案1:字典统一存储(推荐)
这种方式可维护性最高,不会触发属性找不到的报错,也不需要依赖动态绑定的脆弱逻辑:
- 第一步,在类的
__init__初始化方法中提前定义统一的传感器存储容器:def __init__(self): # 键为目标格式的传感器标识,值为对应Quantity对象 self.sensor_storage = {} - 第二步,调整扫描循环逻辑,匹配编号从1递增的规则:
# 共执行5次扫描,序号从1开始逐次递增 for scan_seq in range(1, 6): # 同步采集当次数据,生成对应编号的传感器对象 current_sensor = Quantity( f"HC-SR04.{scan_seq}", Quantity.FLOAT ) # 存入统一存储容器,匹配sensor_1到sensor_5的命名规则 self.sensor_storage[f"sensor_{scan_seq}"] = current_sensor - 后续读取对应扫描数据时,直接通过字典键访问即可,比如要取第2次扫描的传感器,读取
self.sensor_storage["sensor_2"]就和预期完全一致。
方案2:动态绑定实例属性(仅外部接口强制要求时使用)
如果业务逻辑强制要求必须直接通过self.sensor_1这类命名访问属性,不要硬写动态拼接的属性名,要通过Python内置的setattr方法完成绑定,避免属性不存在的报错:
for scan_seq in range(1, 6): current_sensor = Quantity( f"HC-SR04.{scan_seq}", Quantity.FLOAT ) # 动态给实例绑定sensor_1、sensor_2...属性 setattr(self, f"sensor_{scan_seq}", current_sensor)
注意:这种写法后续遍历所有传感器时,需要专门过滤类属性中带
sensor_前缀的条目,维护成本远高于字典存储方案,还容易出现和类内部其他属性重名的冲突,非必要不推荐。
关键避坑点
- 不要直接用字符串拼接的变量名访问实例属性,比如不要尝试写
self[f"sensor_{i}"]这类语法,本质上还是要回到getattr/setattr的标准动态属性操作逻辑上,否则大概率触发属性不存在的报错。 - 记得把循环的起始值从0调整为1,否则生成的第一个传感器编号是0,会和预期的1开始的规则错位。
- 如果需要存储实际采集的数值,只需要在生成Quantity对象时传入当次读取的传感器数据即可,编号生成逻辑不需要做额外调整。
内容的提问来源于stack exchange,提问作者MEKH
相关产品推荐
相关产品推荐

