开源第三篇,代码优化,基于上一篇后续内容,代码如下:
代码
class ReadLogThread(QThread): def __init__(self, Path, SelectText=None, OnelyIphone=None, Devices=None): super().__init__() self.Path = Path self.SelectText = SelectText self.dingding = DingTalkSendMsg() self.OnelyIphone = OnelyIphone self.Devices = Devices self.currentTime = datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S") def run(self) -> None: info = self.Info() if info: self.SendDing(info) with open(sys_ + "\\" + "测试数据.json", "w") as json_file: json.dump(info, json_file, indent=4) # 使用indent参数以漂亮的格式缩进数据 @staticmethod def dataTimes(value, stime, etime): if len(value) >= 12: start_time = datetime.datetime.strptime(stime, '%H:%M:%S.%f') end_time = datetime.datetime.strptime(etime, '%H:%M:%S.%f') else: start_time = datetime.datetime.strptime(stime, '%H:%M:%S') end_time = datetime.datetime.strptime(etime, '%H:%M:%S') over_time = end_time - start_time return str(over_time) def ReadLog(self): with open(self.Path, 'r', encoding="utf-8") as r: datas = r.read() return datas def Info(self): datas = self.ReadLog() Infomations = self.VolCur() capValue = re.findall(r'\[(.*)\].*cap\s*:\s*(\d*)\s*%', datas) statusValue = re.findall(r'\[(.*)\].*status\s*:\s*(\w*)', datas) for key, value in zip(statusValue, capValue): if self.SelectText == '充电': # 充电时长 ChargeTime = self.dataTimes(stime=statusValue[0][0], etime=statusValue[-1][0], value=statusValue[0][0]) # 充电跳电情况 ChargeInfo = self.ChargeInfoBatteryJump() ChargeBat = self.ChargeBatJump() return {"PutTime": ChargeTime, "Currentbattery":capValue[-1][1], "PutInfo": ChargeInfo, "PutBat": ChargeBat, "Infomations": Infomations} elif self.SelectText == "放电": # 放电 # 放电时长 PutTime = self.dataTimes(stime=capValue[0][0], etime=capValue[-1][0], value=capValue[0][0]) # 放电跳电情况 PutInfo = self.PutInfoBatteryJump() PutBat = self.PutBatJump() return {"PutTime": PutTime, "Currentbattery":capValue[-1][1], "PutInfo": PutInfo, "PutBat": PutBat, "Infomations": Infomations} def ChargeInfoBatteryJump(self): """info充电跳电""" datas = self.ReadLog() MaxNumber = [] dictValue = {"JumpNum": 0, "JumpValue": [], "MaxJump": 0} Jump = re.findall(r'\[(.*)\].*cap\s*:\s*(\d*)\s*%', datas) for num in range(len(Jump) - 1): CountNumber = int(Jump[num + 1][1]) - int(Jump[num][1]) if CountNumber > 1: # 充电跳电 dictValue["JumpNum"] += 1 MaxNumber.append(CountNumber) dictValue["JumpValue"].append(Jump[num + 1]) if CountNumber < 0: # 充电掉电 dictValue["JumpNum"] += 1 MaxNumber.append(CountNumber) dictValue["JumpValue"].append(Jump[num + 1]) if MaxNumber: dictValue["MaxJump"] = max(MaxNumber) # print("ChargeInfoBatteryJump",dictValue) return dictValue def PutInfoBatteryJump(self): """info放电跳电数据""" datas = self.ReadLog() MaxNumber = [] dictValue = {"JumpNum": 0, "JumpValue": [], "MaxJump": 0} Jump = re.findall(r'\[(.*)\].*cap\s*:\s*(\d*)\s*%', datas) for num in range(len(Jump) - 1): CountNumber = int(Jump[num][1]) - int(Jump[num + 1][1]) if CountNumber > 1: # 放电回电 dictValue["JumpNum"] += 1 MaxNumber.append(CountNumber) dictValue["JumpValue"].append(Jump[num + 1]) if CountNumber < 0: # 放电跳电 dictValue["JumpNum"] += 1 MaxNumber.append(CountNumber) dictValue["JumpValue"].append(Jump[num + 1]) if MaxNumber: dictValue["MaxJump"] = max(MaxNumber) return dictValue def VolCur(self): """单数是充电电流电压,双数是电池电流电压""" datas = self.ReadLog() ChargeDictValue = {"Start": {"vol": None, "cur": None}, "End": {"vol": None, "cur": None}} BatteryDictValue = {"Start": {"vol": None, "cur": None}, "End": {"vol": None, "cur": None}} volValue = re.findall(r"\[(.*)\].*vol\s*:\s*(\d*)", datas) curValue = re.findall(r"\[(.*)\].*cur\s*:\s*(\d*)", datas) ChargeDict = {"ChargeVol": [], "ChargeCur": []} BatteryDict = {"BatteryVol": [], "BatteryCur": []} if (volValue and curValue) is not False: for num in range(len(volValue)): if num % 2 == 0: # 充电电流电压 ChargeDict["ChargeVol"].append(volValue[num]) ChargeDict["ChargeCur"].append(curValue[num]) else: # 电池电压电流 BatteryDict["BatteryVol"].append(volValue[num]) BatteryDict["BatteryCur"].append(curValue[num]) """充电电压电流数据""" ChargeDictValue["Start"].update({"vol": ChargeDict["ChargeVol"][0][1], "cur": ChargeDict["ChargeCur"][0][1]}) ChargeDictValue["End"].update({"vol": ChargeDict["ChargeVol"][-1][1], "cur": ChargeDict["ChargeCur"][-1][1]}) BatteryDictValue["Start"].update({"vol": BatteryDict["BatteryVol"][0][1], "cur": BatteryDict["BatteryCur"][0][1]}) BatteryDictValue["End"].update({"vol": BatteryDict["BatteryVol"][-1][1], "cur": BatteryDict["BatteryCur"][-1][1]}) # print("VolCur", ChargeDictValue) return {"ChargeDictValue": ChargeDictValue, "BatteryDictValue": BatteryDictValue} def PutBatJump(self): """Bat放电""" BatPutValue = {"JumpNum": 0, "JumpValue": [], "MaxJump": 0} MaxNumber = [] datas = self.ReadLog() values = re.findall('\[(.*)\].*cap\s*:.*,(.*)', datas) if values: for num in range(len(values) - 1): CountNumber = int(values[num][1]) - int(values[num + 1][1]) if CountNumber > 1: """掉""" BatPutValue["JumpNum"] += 1 MaxNumber.append(CountNumber) BatPutValue["JumpValue"].append(values[num + 1]) if CountNumber < 0: """回""" BatPutValue["JumpNum"] += 1 MaxNumber.append(CountNumber) BatPutValue["JumpValue"].append(values[num + 1]) if MaxNumber: BatPutValue["MaxJump"] = max(MaxNumber) return BatPutValue def ChargeBatJump(self): """Bat充电""" BatChargeValue = {"JumpNum": 0, "JumpValue": [], "MaxJump": 0} MaxNumber = [] datas = self.ReadLog() values = re.findall('\[(.*)\].*cap\s*:.*,(.*)', datas) if values: for num in range(len(values) - 1): CountNumber = int(values[num + 1][1]) - int(values[num][1]) if CountNumber > 1: """跳""" BatChargeValue["JumpNum"] += 1 MaxNumber.append(CountNumber) BatChargeValue["JumpValue"].append(values[num + 1]) if CountNumber < 0: """掉""" BatChargeValue["JumpNum"] += 1 MaxNumber.append(CountNumber) BatChargeValue["JumpValue"].append(values[num + 1]) if MaxNumber: BatChargeValue["MaxJump"] = max(MaxNumber) return BatChargeValue def SendDing(self, kwargs): message = f'\n --✉️ {self.Devices} Tests complete-- \n' \ f'\n📌 测试人员:Aiper \n' \ f'\n💡 当前电量:{kwargs["Currentbattery"]} % \n' \ f'\n📆 测试日期:{self.currentTime} \n' \ f'\n⌛ 跑机时长:{kwargs["PutTime"]} \n' \ f'\n📝 跳电次数:{kwargs["PutInfo"]["JumpNum"]} 次 \n' \ f'\n🚀 最大跳电:{kwargs["PutInfo"]["MaxJump"]} \n' \ f'\n ⚡ 开始电流:{kwargs["Infomations"]["ChargeDictValue"]["Start"]["cur"]} ma \n' \ f'\n ⚡ 开始电压:{kwargs["Infomations"]["ChargeDictValue"]["Start"]["vol"]} mv \n' \ f'\n ⚡ 结束电流:{kwargs["Infomations"]["ChargeDictValue"]["End"]["cur"]} ma \n' \ f'\n ⚡ 结束电压:{kwargs["Infomations"]["ChargeDictValue"]["End"]["vol"]} ma \n'\ f'\n📒 详细请参考"测试数据.json"文件。' mobiles = [] if self.OnelyIphone: mobiles.append(self.OnelyIphone) self.dingding.send_ding_notification(message, mobiles) def JsonPath(self, data, path): """取值""" return jsonpath.jsonpath(data, path)
优化代码
上述代码中存在的主要问题:
减少重复读取: 在 Info 函数中多次调用了 self.ReadLog() 来获取日志数据。如果这部分的日志数据不会变化,最好将其在函数开头读取一次,然后传递给其他函数使用。
避免重复正则匹配: 在 ChargeInfoBatteryJump、PutInfoBatteryJump、VolCur 等函数中都使用了正则匹配来提取数据。考虑将这些提取步骤封装到一个单独的函数中,以避免重复的代码。
首先-减少ReadLog重复调用
将ReadLog直接放入到初始化函数中,用一个变量接收,也就是让ReadLog的返回值用一个"实例变量来接收",便于全局调用。写法如下
class ReadLogThread(QThread): def __init__(self, Path, SelectText=None, OnelyIphone=None, Devices=None): super().__init__() self.Path = Path self.SelectText = SelectText self.dingding = DingTalkSendMsg() self.OnelyIphone = OnelyIphone self.Devices = Devices self.currentTime = datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S") self.datas = self.ReadLog() def ReadLog(self): with open(self.Path, 'r', encoding="utf-8") as r: datas = r.read() return datas
至于其他地方,有调用ReadLog的地方,全部注释掉,并将datas = self.ReadLog()的局部变量datas替换成实例变量。如下:
def Info(self): # datas = self.ReadLog() Infomations = self.VolCur() capValue = re.findall(r'\[(.*)\].*cap\s*:\s*(\d*)\s*%', self.datas) statusValue = re.findall(r'\[(.*)\].*status\s*:\s*(\w*)', self.datas)
其次-run函数
在run函数中,我将写入JSON文件的代码写入到了这里,我们用一个函数来替代,如下:
def run(self) -> None: info = self.Info() if info: self.SendDing(info) self.WriteJson(info) def WriteJson(self, info): """写入Json数据""" with open(sys_ + "\\" + "测试数据.json", "w") as json_file: json.dump(info, json_file, indent=4) # 使用indent参数以漂亮的格式缩进数据
最后-正则优化
这里的正则优化指的不是优化正则表达式,而是优化冗余代码,代码中清晰可见有很多重复的正则,例如:
capValue = re.findall(r'\[(.*)\].*cap\s*:\s*(\d*)\s*%', self.datas) statusValue = re.findall(r'\[(.*)\].*status\s*:\s*(\w*)', self.datas)
然而优化有,我们直接:
def ReExpression(self): self.capValue = re.findall(r'\[(.*)\].*cap\s*:\s*(\d*)\s*%', self.datas) self.statusValue = re.findall(r'\[(.*)\].*status\s*:\s*(\w*)', self.datas) self.volValue = re.findall(r"\[(.*)\].*vol\s*:\s*(\d*)", self.datas) self.curValue = re.findall(r"\[(.*)\].*cur\s*:\s*(\d*)", self.datas) self.batValues = re.findall('\[(.*)\].*cap\s*:.*,(.*)', self.datas)
直接写入一个函数,命名小驼峰的方式,见名知意即可。然后在初始化函数中调用这个函数,激活即可使用了。其他相同正则的地方,直接注释掉,变量改用此处的变量即可,例如:
def ChargeInfoBatteryJump(self): """info充电跳电""" # datas = self.ReadLog() MaxNumber = [] dictValue = {"JumpNum": 0, "JumpValue": [], "MaxJump": 0} # Jump = re.findall(r'\[(.*)\].*cap\s*:\s*(\d*)\s*%', self.datas) for num in range(len(self.capValue) - 1): CountNumber = int(self.capValue[num + 1][1]) - int(self.capValue[num][1]) if CountNumber > 1: # 充电跳电 dictValue["JumpNum"] += 1 MaxNumber.append(CountNumber) dictValue["JumpValue"].append(self.capValue[num + 1]) if CountNumber < 0: # 充电掉电 dictValue["JumpNum"] += 1 MaxNumber.append(CountNumber) dictValue["JumpValue"].append(self.capValue[num + 1]) if MaxNumber: dictValue["MaxJump"] = max(MaxNumber) # print("ChargeInfoBatteryJump",dictValue) return dictValue
当然,还有另一个优化方式,那就是封装一个正则匹配函数。如:
def findatches(regex, data): return re.findall(regex, data)
其他地方进行调用,如:
def info(self): capRegex = r'\[(.*)\].*cap\s*:\s*(\d*)\s*%' capValue = re.findall(cap_regex, self.datas)
结语
感谢阅读。gitee地址:
https://gitee.com/qinganan_admin/Pyqt5_Battery_MONITOR_SYSTEM.git