介绍:

热更新,就是在服务器不重启的的情况下,对游戏增加新的功能或者修复出现bug 的代码。游戏更新迭代速度快,催生了热更技术的需求,在我经历过的游戏项目中,无论是服务端还是客户端,版本的更新都是围绕着热更新,特别是现在游戏动辄几个G,每次让玩家下载完整的包不现实,随意游戏必须要支持热更。下面来谈一下客户端Python热更新的处理。

原理:

1.标准import

都知道Python提供了import可以导入一个标准的python模块,将模块载入内存,并加到sys.modules中。但是多次import同一模块只是将名称导入到当前的Local名字空间,也就是一个模块不会重复载入,所以想要热更靠这个特性是不行的。此路不通,请换个思路。

2.reload函数

reload()函数可以重新载入已经导入的模块,这样似乎就可以热更新Python的代码了。但是python原生的reload函数太过简单,不足以支撑游戏的热更新需求,主要原因有几个: reload重新加载的模块不会替换旧版本的模块,也就是已经引用的旧模块无法更新 同样因为不能旧对象的引用,使用from ... import ... 方式引用的模块同样不能更新 reloas(m)后,class及其派生class的实例对象,仍然使用旧的class定义。 同时加载模块失败时候,没有回滚机制,导致需要重新import该模块 因此,结合游戏的热更新需求,自定义合适的reload。新的自定义reload目的是为了达到在原程序不结束的情况下,让程序能动态加载改动后的代码。主要想达到下面两点: 提升开发效率 在游戏不重启的情况下修复紧急BUG

## 实现:

热更新最核心的需求就是让python解释器执行最新的代码,同时保证其他关联模块不会出现问题。对于刷新function,class内定义的method比较容易实现,但对于刷新module内定义的变量,class内定义的变量,还有新增加的成员变量,则需要有统一的约定。所以在实现热更新过程中,我们需要考虑好代码更新和数据更新这两点,下面罗列一下新的reload具备哪些特性:

- 1.更新代码定义

(function/method/static_method/class_method) 不更新数据(除了代码定义外的类型都当作是数据) 在module中约定reload_module接口,class中约定reload_class接口,在这两个接口中手动处理数据的更新,还有更多的约定和接口待完成 替换函数对象的内容

```
# 用新的函数对象内容更新旧的函数对象中的内容,保持函数对象本身地址不变
def update_function(oldobj, newobj, depth=0):  setattr(oldobj, "func_code", newobj.func_code)  setattr(oldobj, "func_defaults", newobj.func_defaults)  setattr(oldobj, "func_doc", newobj.func_doc)
```

2.替换类的内容


# 用新类内容更新旧类内容,保持旧类本身地址不变
def _update_new_style_class(oldobj, newobj, depth):  handlers = get_valid_handlers()  for k, v in newobj.__dict__.iteritems():  # 如果新的key不在旧的class中,添加之  if k not in oldobj.__dict__:  setattr(oldobj, k, v)  _log("[A] %s : %s"%(k, _S(v)), depth)  continue  oldv = oldobj.__dict__[k]  # 如果key对象类型在新旧class间不同,那留用旧class的对象  if type(oldv) != type(v):  _log("[RD] %s : %s"%(k, _S(oldv)), depth)  continue  # 更新当前支持更新的对象  v_type = type(v)  handler = handlers.get(v_type)  if handler:  _log("[U] %s : %s"%(k, _S(v)), depth)  handler(oldv, v, depth + 1)  # 由于是直接改oldv的内容,所以不用再setattr了。  else:  _log("[RC] %s : %s : %s"%(k, type(oldv), _S(oldv)), depth)  # 调用约定的reload_class接口,处理类变量的替换逻辑  object_list = gc.get_referrers(oldobj)  for obj in object_list:  # 只有类型相同的才是类的实例对象  if obj.__class__.__name__ != oldobj.__name__:  continue  if hasattr(obj, "x_reload_class"):  obj.x_reload_class()

- 3.staticmethod 静态方法

def _update_staticmethod(oldobj, newobj, depth):  # 一个staticmethod对象,它的 sm.__get__(object)便是那个function对象  oldfunc = oldobj.__get__(object)  newfunc = newobj.__get__(object)  update_function(oldfunc, newfunc, depth)

- 4.classmethod 类方法

def _update_classmethod(oldobj, newobj, depth):  oldfunc = oldobj.__get__(object).im_func  newfunc = newobj.__get__(object).im_func  update_function(oldfunc, newfunc, depth)

模块的更新也是相类似,就不一一粘贴了,只是在原来的reload基础上进行改良,对于模块热更新,还约定了一个reload_module接口,可以自定义数据的更新。 下面添加一些用例:

def x_reload_class(self):  """ 热更新后,每个重新对象的实例都会执行这个函数 由于新老对象的替换不会重新调用构造函数,因此有必要对热更新的类对象执行初始化逻辑 处理新老变量的修复,函数执行环境的修复 """  self._new_var = 5000    # 新变量的初始化  self.runLogic()      # 新修复的逻辑

总结:
只是在基础的reload模块上做了一些定制,让热更新更适合游戏的开发节奏,而不是简单暴力的reload模块

Python在游戏中的热更新相关推荐

  1. 初学者学习 - Unity中的热更新 - Lua和C#通信

    菜鸟学习 - Unity中的热更新 - Lua和C#通信 孙广东 2015-4-6 热更新我是个菜鸟,感谢网上的各位的奉献,这次又当一回搬运工. 准备: 1.了解Lua的语法 推荐书籍<Lua程 ...

  2. Unity中的热更新的基础知识,Xlua与ILRuntime基础知识

    1.什么是热更新 热更新是指在不需要重新编译打包游戏的情况下,在线更新游戏中的一些非核心代码和资源,比如活动运营和打补丁.热更新分为资源热更新和代码热更新两种,代码热更新实际上也是把代码当成资源的一种 ...

  3. 菜鸟学习 - Unity中的热更新 - Lua和C#通信

    孙广东 2015-4-6 热更新我是个菜鸟,感谢网上的各位的奉献,这次又当一回搬运工. 准备: 1.了解Lua的语法 推荐书籍<Lua程序设计 第二版> 2.使用ULua插件进行通信 尽量 ...

  4. Unity中的热更新 - Lua和C#通信

    准备: 1.了解Lua的语法 推荐书籍<Lua程序设计 第二版> 2.使用ULua插件进行通信 尽量早上真机.因为Bug问题特别多. 大杂烩: 更新LUa其实也是更新资源. Lua被看作一 ...

  5. android中的热更新

    热更新的流程 1.线上检测到严重的crash 2.拉出一个bugfix分支并在分支上修复问题 3.jenkins构建和补丁生成. 4.app通过推送或者主动拉取补丁文件 5.将bufix代码合并到ma ...

  6. Java游戏服务器代码热更新

    一般碰到这个问题首先想到的解决方案都是考虑new 一个classLoader来加载新的类,这样的解决方式有什么优点和缺点呢. 使用ClassLoader的方式加载类就涉及到一些需要知道的知识点.双亲委 ...

  7. python文字游戏循环3次_如何停止迭代for循环以便玩家可以在Python迷宫游戏中移动?...

    我使用的是Python 3,而且我非常非常缺乏经验,所以请善待.我有一个迷宫游戏,也是一个语言词汇游戏.除了一件事之外,一切都像是应该的.当玩家滚过"黄金"并弹出问题时,for循环 ...

  8. 苹果为什么要禁止 JSPatch 等热更新技术?

    声明:本文为作者投稿,CSDN 基于原文进行了完善,版权为原作者所有,未经作者允许,请勿转载. [CSDN有奖征稿啦]技术之路,共同进步,有优质移动开发.VR/AR/MR.物联网原创技术文章欢迎发送邮 ...

  9. 怎么理解游戏热更新中的“母包”和“补丁”

    我们玩过游戏的都有过这样的经历,一个游戏安装好之后,啥都不用管,每次点开游戏之后读个条,游戏内容就始终是最新的,可能有新的道具.新的活动,可能某个东西过些日子就找不到了. 当我们学过怎么做游戏之后,我 ...

最新文章

  1. .NET Core微服务之基于Ocelot+IdentityServer实现统一验证与授权
  2. 从命令行运行postman脚本
  3. 【数据结构与算法】之深入解析“合并区间”的求解思路与算法示例
  4. 【UOJ575】光伏元件【网络流建图】【上下界网络流】【费用流】
  5. iOS开发API常用英语名词
  6. 2017.9.29 road 失败总结
  7. C++共享内存类封装
  8. C++ 在线IDE 编译器
  9. 在线SVG转换,支持SVG to PNG、SVG to JPEG、SVG to WEBP 图片转换操作-toolfk程序员在线工具网
  10. 【防火墙_策略路由】
  11. 生活随记 - 值班后第二天晚上失眠小记
  12. 原创仿虎哥说车抖音文案,抖音策划,虎哥说车文案背景音乐,房子租凭宣传文案
  13. 苹果电池显示维修_苹果财大气粗:维修换电池?直接给你换个机
  14. Vue报错 component lists rendered with v-for should have explicit keys.
  15. Android仿腾讯手机管家实现桌面悬浮窗小火箭发射的动画效果
  16. SQL+Tableau化妆品数据分析
  17. 【电源专题】什么是开关稳压器
  18. TOPSIS法(优劣解距离法)笔记
  19. 关于发送邮件的几种方式
  20. 在C语言中使用Esc退出的程序,C如何使用ESC按钮终止我的程序

热门文章

  1. uoj311 【UNR #2】积劳成疾
  2. html中seo三大标签,探索者SEO告诉你三大标签如何正确使用
  3. 计算机高水平竞赛,国际类高水平的竞赛有哪些?
  4. 基于红外感应的远距离智能跟随小车,自动跟随小车
  5. 比较好的刷题网站推荐
  6. 【C语言编程】简单密码
  7. 嵌入式linux环境取得U盘容量等信息的方法
  8. Android绘制地图
  9. 计算机最新行情调研报告,2020年中国笔记本电脑市场调研报告
  10. 主播直播时如何选择合适的内容?如何打造主播人设?