Python如何自动创建编号变量 实现树莓派DHT22传感器批量数据处理
你之前尝试迭代却失败,核心是陷入了“必须生成dht1/t1/h1这类带编号的独立变量”的思维误区,这类动态拼变量名的写法不仅不优雅,后续维护成本极高。Python里处理同类重复对象的最优方案,是把同类实例、采集到的数值全部存在统一的列表结构里,全程靠索引遍历完成操作,完全不需要写重复的逐行赋值代码。
第一步:批量初始化传感器,替代重复实例化代码
把所有传感器对应的GPIO引脚提前整理成清单,用列表推导式循环生成所有传感器实例,不用逐行写三次dht.DHT22(引脚)的重复代码,写法完全匹配你原来的库引用习惯:
import board import adafruit_dht as dht # 传感器引脚清单,后续新增/调整传感器只需要改这里 SENSOR_PINS = [board.D26, board.D19, board.D13] # 循环初始化全部DHT22传感器,存在统一列表里 sensors = [dht.DHT22(pin) for pin in SENSOR_PINS]
初始化完成后,sensors[0]对应你原来代码里的dht1,sensors[1]对应dht2,sensors[2]对应dht3,逻辑完全和原有代码对齐。
第二步:迭代读取传感器数值,替代逐行读值的重复操作
遍历传感器列表,逐次读取温度、湿度值,把结果分别存在温度列表、湿度列表里,不用生成t1/t2/h1/h2这类零散变量:
temperatures = [] humidities = [] for sensor in sensors: # 加上DHT传感器必备的读值容错(这类传感器偶尔会读值失败,没容错很容易让程序崩溃) try: temp = sensor.temperature hum = sensor.humidity temperatures.append(temp) humidities.append(hum) except RuntimeError: # 读值失败时补占位标记,避免后续计算报错 temperatures.append(None) humidities.append(None)
第三步:统一处理显示字符串、计算平均值
原来逐行写的str()类型转换、平均值计算,全部可以靠列表操作批量完成:
# 批量生成LCD显示用的字符串列表,对应你原来的t1s/t2s/t3s、h1s/h2s/h3s temp_strs = [str(t) if t is not None else "读取失败" for t in temperatures] hum_strs = [str(h) if h is not None else "读取失败" for h in humidities] # 计算有效数据的平均值,自动过滤读值失败的空值 valid_temps = [t for t in temperatures if t is not None] tavg = round(sum(valid_temps)/len(valid_temps), 1) tavgs = str(tavg) valid_hums = [h for h in humidities if h is not None] havg = round(sum(valid_hums)/len(valid_hums), 1) havgs = str(havg)
之前for i in range(1,3)尝试失败的原因
很多新手入门时会尝试用globals()[f'dht{i}']这类写法动态生成带编号的独立变量名,这种写法虽然能临时跑通,但本质上还是在生成一堆零散的离散变量,后续你读值、算平均、传LCD显示的时候,还是要逐一把这些动态生成的变量捞回来用,根本达不到“减少重复代码”的目的,反而因为变量没有统一的容器,后续加传感器、改引脚的时候要改动大量逻辑。
另外你写的range(1, 3)本身也踩了Python的经典语法坑:Python的range是左闭右开的区间,这个写法只会循环取i=1、i=2,根本覆盖不到第三台传感器,哪怕动态拼变量名的逻辑没问题,也会漏掉最后一台设备。
这套写法的实际优势
- 代码量比你原来逐行编写的版本少60%以上,没有重复的赋值操作
- 后续要新增第四台、第五台传感器时,只需要把对应的GPIO引脚加到开头的
SENSOR_PINS列表里,后面所有读值、算平均、生成显示文本的逻辑一行都不用改 - 自带读值容错,解决DHT22硬件偶尔读值失败导致程序崩溃的常见问题
内容的提问来源于stack exchange,提问作者hoipolloimike

