Python代码优化篇(适合有基础的童鞋)

简介: Python代码优化篇(适合有基础的童鞋)

开源第三篇,代码优化,基于上一篇后续内容,代码如下:

代码

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


目录
相关文章
|
6月前
|
存储 并行计算 Java
Python代码优化与性能调优:提升效率的关键技巧
在当今快节奏的软件开发环境中,优化Python代码的性能成为了开发者们关注的焦点。本文将介绍一些实用的技巧和策略,帮助开发者们最大限度地提高Python代码的执行效率,从而使应用程序更加高效稳定。
|
Python
80 python - 打飞机案例(代码优化-抽象出基类)
80 python - 打飞机案例(代码优化-抽象出基类)
38 0
|
2月前
|
存储 缓存 分布式计算
|
3月前
|
存储 分布式计算 并行计算
Python代码优化秘籍:让你的代码跑得更快、更稳定!
Python因易读性和强大的库支持而流行,但其性能常不及C/C++。本文分享五大秘籍助你优化Python代码:精选数据结构提高查找效率;精简循环与递归,善用列表推导式;利用高效内置函数及库如NumPy;优化内存管理,适时释放资源;采用并行与分布式计算加速处理。实践这些技巧,让Python代码更高效、稳定!
81 1
|
3月前
|
存储 缓存 算法
Python中的代码优化
【8月更文挑战第2天】Python虽简洁强大,但在处理大数据或高性能需求时可能遇到效率挑战。本文介绍13种Python代码优化技巧,包括选用高效数据结构、避免不必要循环、利用生成器、并发编程、第三方库、内置函数、结果缓存、数据序列化、编译优化、延迟计算、内存管理及性能分析工具等,配以示例代码,助您提升程序性能。
58 3
|
4月前
|
存储 Python
Python代码优化使用生成器(Generators)
【7月更文挑战第22天】
65 5
|
4月前
|
缓存 算法 Python
python代码优化
【7月更文挑战第21天】
52 5
|
4月前
|
Python
Python代码优化避免全局变量
【7月更文挑战第22天】
57 2
|
4月前
|
Python
|
4月前
|
Python
告别代码冗余!Python闭包与装饰器如何让你秒变代码优化大师?
【7月更文挑战第6天】Python的闭包和装饰器是解决代码冗余的利器。闭包,如匿名函数,记忆外部作用域变量,实现代码封装。例如,`make_multiplier_of`生成特定乘法函数,避免重复。装饰器如`@my_decorator`,不修改原函数,添加额外功能,如在函数调用前后打印信息。两者结合,提升代码灵活性和复用性,是优化和整洁代码的关键。
30 0
下一篇
无影云桌面