Python的reload及热更新

                       Python的reload及热更新

                      Horin | horin153@msn.com
                      Blog: http://blog.csdn.net/horin153/

        reload 的目的是为了开发期的 "edit and debug"/即编即调,这对每次启动就是一项大工程的 MMO 游戏,是非常实用的。热更新是为了运营期的 "fix online"/在线修复,对任何在线游戏而言,这是多少程序员的梦想啊!回想几年前用 c++ 做的游戏项目,每周的例行更新维护就是一个恶梦:前一天晚上要加班到凌晨,第二天早上 patch 刚放出,就被发现了 bugs。轻者就让玩家忍受到下周的 patch 进行修正;如果严重,只好紧急灭火,停机更新 patch 的 patch。除了极差的用户体验,导致玩家流失外;开发人员的这种日子一个字苦!两个字真苦!
 
        可爱的 Python 为了让程序员从地狱升入天堂,内建了函数 reload(module) ,希望借此解决上述难题。这个愿景绝对美好,至于你信不信,由你,我反正是信的!由于 Python 仍处于发展的初级阶段,reload 的实现就有点掉链子了:
 
[1] 不是打 patch(可以有旧对象删除、有新对象增加、有旧对象修改);而是把 reload 时生成的新对象替换掉同名旧对象;无法删除旧对象。
[2] reload(m)后,用 from m import obj 方式导入的 obj 仍然指向旧的 obj。
[3] reload(m)后,class 及其派生 class 的实例对象,仍然使用旧的 class 定义。

        问题 1 浪费了部分内存,无所谓,反正内存早就是 GB 时代了。问题 2 可以用 import m 方式解决,强迫自己改变编码风格就可以了,也可以忍受。问题 3 却是压死 reload 的最后一根稻草了:面向对象编程的核心就是 class,搞不定 class 就没有 reload!

        自从 reload 面世后,有识之士有感于其不作为,提出了由浅入深、由易到难的不同完善方案,推荐参看下述链接:
           http://code.google.com/p/reimport
在此我提醒一下,上述几个项目目标是美好的,但因为各种原因,其实现可能远不如宣传的那样中意。但作者的奉献精神仍然值得尊敬,其实现思路也很值得参考。


        世界是平的,轮子是圆的。有这么多 reload 方案存在,我们也就不需要重新造轮子了。只需要挑选一个合适的实现方案,再结合项目的实际需要进行下加工就可以了。
 最常见的情景是:修改了 function/method 的实现、更新了导表数据。把这两个问题解决,就可以用 20% 的付出,收获 80% 的回报。鉴于此,我从上述几个项目中选择了最简单的 xreload,其实现思路是:在临时 namespace 中执行 module,再在原地(in place)对 classes, methods and functions 打 patch。因为是原地打 patch,也就避免了对 class 的实例打 patch,这也是该项目的最大优点。

         我对 xreload 模块进行了以下修改:
*增加对 new style class 的支持。
 可能是写的太早的缘故,xreload 仅处理了 classic class,不能处理新式类。
*增加对 module 的可变容器(list,dict,set)的原地更新。
 这主要是为了解决导表数据、配置参数的更新。
*增加对 metaclass 的支持。
 metaclass 可以把一些复杂应用化繁为简,应该支持。
*增加对 module 全局变量的支持。
 这主要是为了解决用模块级 global 变量来实现 singleton 模式的更新问题。在 reload 后,会恢复 global 变量。

         修改后的 xreload 可以胜任以下应用:
*可以用 module 或者有 '__module__' 属性的对象来作 reload 的参数。
*可以对 classes, methods and functions 打 patch。
 也就是可以支持上述对象的增加、删除、修改、重命名。
*支持 classmethod and staticmethod,其他 decorator 不支持。
 @2011.08.29
 增加对 decorator 等闭包的支持(仍然支持 classmethod and staticmethod)。
 因为现在的项目中大量使用了 decorator 等闭包,经过不断的 google 与试验,总算解决了这个最大的遗留问题。
*支持 from m import obj 方式,但要求 obj 是可变的,如 class/dict/list 等。
*支持 metaclass。
*支持 module 的 global 变量。

         当有需要时,可以增加以下功能:
*自动 reload 有变化的 module。
 该功能比较容易实现,只需要定期遍历各个 module 并比较其时间戳,但因为不大实用,暂不实现。
*增加对 slots 的支持。
 我简单试了下,没有搞定。因为目前没有使用,也就不深究了。slots 的好处是省内存,在项目中有使用时可以支持。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值