iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python 软件热更新
  • 955
分享到

Python 软件热更新

软件Python 2023-01-31 00:01:02 955人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

本篇文章涉及技术知识如下: Redis threading 多线程 PyQt5 importlib 热更新 场景 咱们在平时运行一些长时间都会一直运行的软件(如:某些云同步软件)的时候,某些功能因为考虑的情况可能不充分,导致体验不

本篇文章涉及技术知识如下:

Redis
threading 多线程
PyQt5

importlib 热更新

场景

咱们在平时运行一些长时间都会一直运行的软件(如:某些云同步软件)的时候,某些功能因为考虑的情况可能不充分,导致体验不够好的时候,很多人都会忽视这个问题,除非这个问题影响到他正常使用了。但是也有部分用户会在软件的反馈框里面将问题反馈给开发者,顺带将错误日志也一并提交给开发者。然后过了一天或者半天,你再运行那部分功能的时候,发现问题已经解决了。可是,我们都没有更新软件呀,甚至连软件都没有重启,难道前面遇到的那个情况真的是因为自己太幸运踩中bug了吗?
其实,我们之前遇到的问题,可能的确就是一个bug,但是在反馈问题给开发者后,开发者快速定位问题所在后,通过热更新将问题解决了。相当于我们使用的软件自动fix了一些bug,更新了一次版本。
那么,今天咱们聊一下热更新这个东西怎么样?我们也随意做个小demo看看这个有意思的功能是怎么做到的。

什么是热更新

热更新就是可以在进程不重启的情况下,让其重新加载修改后的程序代码,且能按照预期正确执行。在实际开发中,热更新的最主要用途有,

  • 可以提升开发效率,让改动后的代码效果立刻实现,避免频繁重启
  • 对于bug修复来说,在CS模式下,如果不是大的bug而是小bug的修复就不用发布比较大的补丁和更新文件了,直接使用服务器修正问题后,通知客户端重新加载修正后代码即可。

python的代码是通过module进行组织的,所以,对某些功能的热更新就是可以通过对module更新就可以了。
Python中,如果重新import 一个已经被import的模块时,并不会重新执行import新的模块。所以,在这个时候,我们希望可以重新加载模块的时候,就需要对模块进行删除后,再重新import进来。
而在sys.modules保存了已经加载过的模块。

 

 

为了方便看到展示,我就沿用上次客户端的界面,进行简单修改后,展示给大家看,热更新的效果。

 

 

左边的按钮是运行模块加载进来的函数,右边的按钮是手动点一下热更新。便于本地手动调试热更新。在后面实现的“发布订阅”情况中,服务端发布更新消息后,不用手动点 热更新 就可以对软件进行自动更新了。

简单实现一个demo,引用myfunction这个模块,运行里面的某个函数一两次后,修改那个被运行的函数实现,然后对myfunction这个模块进行热更新,看看效果怎么样?

 

 

在热更新前,随机产生的数字在原函数里面,版本号为0.0.1,是可以比较明显看出 两个数 是运行 “相加” 操作的。
点击了热更新Button后,软件并未重启,在更新后,可以 看到功能版本号发生了改变,变成了0.1.1,说明已经是热更新完成了的。再点击运行功能,可以看到结果已经变成了 两个数字 进行了 “相减‘ 操作。

完成了本地测试热更新成功后,就着手实现CS模式下的“发布订阅”消息通知功能,利用服务器对客户端推送一个更新指令,客户端就会自动更新模块。
用过Redis的同学应该都知道Redis本身就自带了“发布订阅”功能,借助它,可以很方便的实现出远程推送消息的需求,我们甚至可以用这个功能实现一个简单的聊天室软件哦。
在Redis服务端中,创建一个 update频道:

SUBSCRIBE update

然后在Python中导入Redis模块后,链接到远程Redis数据库后,订阅我们的update频道,再启动一个新的线程去监听update频道的消息。
因为如果直接在代码里面用单线程去监听消息的话,会造成线程阻塞在监听消息哪里,导致界面刷新不出来。所以,我们只要导入threading库,再把监听消息做成一个函数,放到thread中去运行就可以了。由此避免线程阻塞问题。

接着我在本地修改一下myfunction模块后,就到Redis服务的终端中,发布一个消息,reload。
这个时候,软件就会收到reload消息,对刚才被我修改后的模块进行热更新,即删掉源模块,再重新导入一次。
在这里我就不写一次从服务器中下载新的模块文件的代码了,假设我刚才修改后的那个文件就从服务器下载下来的。同学们可以借助前面两篇写软件更新服务的文章来自己实现一个文件下载更新的代码。很简单的,只要你愿意写。

在Redis中发布重载的消息后,订阅了这个频道的客户端,将会接收到更新信息,比如我这个客户端,将会对模块重新加载进行热更新了。
在这里我给大家随意扯一下“灰度测试”吧,这个灰度测试就是软件即将要更新某个功能,但是可能这个功能还不够稳定,不能向全部用户推送新的功能。所以,这个时候,就需要对部分用户更新这个功能,通过这部分用户使用情况来决定灰度测试的范围,比如将5%的范围扩展到10%这样。
至于怎么筛选出那些用户为测试用户呢?其中有个办法是可以用个哈希函数对用户某个值,如用户名,进行处理,符合的就推送。当然还有很多很多的策略,实现执行起来的时候,也不会像我说的那么简单,感兴趣的同学可以自行查阅资料。

接下来,我们来测试一下发布更新功能的消息后,有没正常热更新功能。

 

 

 

 

在这里要提醒一下,如果你在热更新前导入的模块生成了一个对象x,这个时候,你热更新了,然后又生成一个对象y。这个时候,你会发现,x指向的仍旧是旧的那个类,而y则指向了新的类。这个时候,可以通过修改x的__class__属性来对 x 的类进行强制修改,可以这样写:

x.class == y.你的类

但是即使你是这样写,你x里面的数据仍旧不会发生改变的哦。我们只更改了代码的执行逻辑。
代码放这里了:

    python    61行

# -*- coding: utf-8 -*-
# @Time    : 4/12/2019 14:02
# @Author  : MARX·CBR
# @File    : __init__.py.py
import threading
import sys
from PyQt5 import QtWidgets
from updateServer.HotUpdate import myfunction
import redis
import random
import importlib
from updateServer.HotUpdate.HotFixSample import Ui_MainWindow


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.fun = importlib.import_module("myfunction")
        self.pushButton.clicked.connect(self.runFunction)
        self.pushButton_2.clicked.connect(self.hotfix)
        self.ip = "47.xxx.xxx.xx"
        self.redisport = 2017
        self.redis_manager = redis.StrictRedis(self.ip, port=self.redisport)
        # self.textBrowser.append(str(sys.modules))
        print(sys.modules)
        self.tunnel = self.redis_manager.pubsub()
        self.tunnel.subscribe(["update"])
        self.threads = []
        self.t1 = threading.Thread(target=self.autoReload, )
        self.threads.append(self.t1)
        self.threads[0].setDaemon(True)
        self.threads[0].start()

    def autoReload(self):

        for k in self.tunnel.listen():
            if k.get('data') == b'reload':
                self.hotfix()

    def runFunction(self):
        version = self.fun.AllFunction().version
        self.textBrowser.append("功能运行,当前版本为:" + version)
        for i in range(4):
            x = random.randint(-454, 994)
            y = random.randint(-245, 437)
            self.textBrowser.append(str(x) + "\tfunction version {}\t".fORMat(version) + str(y) + " = " + str(
                self.fun.AllFunction().second(x, y)))
        # self.textBrowser.append(self.fun.AllFunction().first())

    def hotfix(self):
        del sys.modules["myfunction"]
        self.fun = importlib.import_module('myfunction')
        self.textBrowser.append("热更新完毕")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())
 

总结


 在本篇文章中,我们讲到了Python的热更新的一些简单用法,以及一些值得注意的坑。顺手应用了Redis的“发布订阅”功能来通知客户端更新功能,扯了一下“灰度测试”。本篇文章代码已同步上传到我GitHub中,欢迎大家fork使用,顺手给个star就更好了,
项目链接:https://github.com/97CBR/SoftwareUpdateServer

    其实,有心思的小伙伴肯定会有更多的想法。比如:我们既然可以动态重新加载一个类来fix bug,也肯定可以动态添加我们要的功能啦。这意味着,我们可以编写出一个软件,具有插件功能的软件。在主体软件上面,运行插件来扩展更加多的功能,和Chrome这样的浏览器一样,安装插件什么的。

推荐阅读:
软件更新服务之服务端搭建
软件更新服务之客户端更新
是谁让我的线上测试服务器突然变成游戏私服

本文对你有没帮助呀,喜欢的话,记得留言、点赞、转发哟。谢谢各位!



扫码关注微信公众号

 

--结束END--

本文标题: Python 软件热更新

本文链接: https://www.lsjlt.com/news/182265.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python 软件热更新
    本篇文章涉及技术知识如下: Redis threading 多线程 PyQt5 importlib 热更新 场景 咱们在平时运行一些长时间都会一直运行的软件(如:某些云同步软件)的时候,某些功能因为考虑的情况可能不充分,导致体验不...
    99+
    2023-01-31
    软件 Python
  • Python-使用watchdog热更新
    直接上代码: import importlib from watchdog.observers import Observer from watchdog.events import * class ScriptEventHa...
    99+
    2023-01-31
    Python watchdog
  • Unity3d热更新(一):更新思路
    目前Unity手游的热更新基本采用如下思路:首先将资源打包成AssetBundle。如果有两个对象共同依赖于同一个对象,需要采用依赖关系打包。AssetBundle需要根据不同的平台打包,各平台之间不能混用,如IOS和Android。为打包...
    99+
    2023-01-31
    思路 Unity3d
  • ubuntu怎么更新软件源
    要更新Ubuntu的软件源,可以按照以下步骤操作:1. 打开终端,可以使用快捷键`Ctrl + Alt + T`打开。2. 输入以下...
    99+
    2023-10-12
    ubuntu
  • ubuntu18.04如何更新软件源
    ubuntu18.04更新软件源的方法:1、打开终端;2、输入命令备份原有软件源文件;3、打开sources.list文件并添加新的软件源地址;4、输入命令更新系统软件源地址即可。具体操作方法如下:使用快捷键【ctrl+alt+t】打开终端...
    99+
    2022-10-11
  • 更新win11软件还在吗
    本篇内容主要讲解“更新win11软件还在吗”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“更新win11软件还在吗”吧!更新win11软件还在吗答:所有软件都在。 正常情况下,更新win11是会保...
    99+
    2023-07-01
  • uniapp实现热更新
    随着移动开发的发展,热更新已经成为了一个非常重要的功能,可以让应用程序在不需要再次发布的情况下,及时地修正bug并添加新特性。而对于uniapp来说,热更新是一种非常重要的解决方案,因为它可以同时支持多个平台,并且实现起来也比较简单。在本文...
    99+
    2023-05-22
  • nodejs实现热更新
    随着web应用的不断发展,JavaScript已经成为前端以及后端开发中的重要语言之一。而Node.js则是一种基于JavaScript的开源、跨平台的运行时环境。尽管Node.js的热度不如几年前,但它仍然是一个强大的工具,为前端/后端开...
    99+
    2023-05-17
  • U3D热更新技术
    @作者 : SYFStrive @博客首页 : HomePage 📌:个人社区(欢迎大佬们加入) 👉:社区链接🔗 🤷‍♀️:创作不易转发需经作者同意😈...
    99+
    2023-08-20
    3d ios c#
  • golang热更新原理
    Go语言的热更新原理主要通过以下四个步骤实现:1、通过监视源代码文件或指定目录,检测文件内容的变化;2、当文件发生变化时,使用Go的工具链重新构建被修改的代码包或整个程序;3、通过使用plugin包或reflect等反射机制,将新的代码加载...
    99+
    2023-12-18
    go语言 Golang golang热更新
  • Python在游戏中的热更新实现
    目录介绍:原理:1.标准import2.reload函数实现:总结:介绍: 热更新,就是在服务器不重启的的情况下,对游戏增加新的功能或者修复出现bug 的代码。游戏更新迭代速度快,...
    99+
    2022-11-12
  • python中的热更新或动态加载
    遍览网络中关于动态加载模块的文章,发现有两种方法,一种是用守护进程的方法,一种是用python自带的reload函数。 比较靠谱的文章是如下两篇: https://my.oschina.net/1123581321/blog/168720...
    99+
    2023-01-31
    加载 动态 python
  • Android中的全量更新、增量更新以及热更新
    在客户端开发过程中,我们可能会遇到这样一种需求:点击某个按钮弹出一个弹窗,提示我们可以更新到apk的某个版本,或者我们可以通过服务端接口进行强制更新。在这种需求中,我们是不需要通过应用商店来更新我们的...
    99+
    2023-09-14
    android java android studio
  • Kali Linux软件更新日报20190622
    Kali Linux软件更新日报20190622...
    99+
    2023-06-05
  • Ubuntu怎么禁止软件更新
    这篇文章主要讲解了“Ubuntu怎么禁止软件更新”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Ubuntu怎么禁止软件更新”吧!一、不升级指定软件的技巧1、以synergy为例,需使用sud...
    99+
    2023-06-27
  • Linux系统【Centos7】更新内核更新软件详细教程
    更新内核: 打开终端,输入命令 sudo yum update,等待更新完成。 重启系统,输入命令 sudo reboot。 在 GRUB 引导界面,选择最新的内核版本,按下回车键进入系统。 在终端中输入命令 uname -r,查看...
    99+
    2023-10-01
    linux 服务器 centos
  • 什么是Android Multidex热更新
    一、Android Multidex热更新 Multidex热更新是指在不重启应用的情况下,通过后台向app推送一个fix、dex文件,等这个文件下载完成,app提示用户发现新的更新,需要重启app。待用户重启,代码修复即会生效。 Andr...
    99+
    2023-10-29
    Android Multidex
  • 全面讲解CocosCreator热更新
    目录前言什么是热更cocos热更概述manifest工程资源和游戏包内资源的区别searchPaths搜索路径cocos的基础热更流程_localManifest:当前包内的mani...
    99+
    2022-11-12
  • docker热更新怎么实现
    Docker 热更新可以通过以下几种方式来实现: 使用 Docker Compose:可以使用 Docker Compose 来...
    99+
    2023-10-27
    docker
  • react 怎么实现热更新
    本教程操作环境:Windows10系统、react18版、Dell G3电脑。react 怎么实现热更新?[React] create-react-app 实现热更新一、使用以下命令行下载 react-hot-loaderyarn add ...
    99+
    2023-05-14
    React
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作