武林秘籍:如何实现代码热更新

经过 Python 虚拟机、函数机制和类机制的学习,我们对 Python 程序执行过程的动态性已经了如指掌:

  • 在运行时,Python 可以动态创建 函数 对象;
  • 在运行时,Python 可以动态创建 类 对象;
  • 在运行时,Python 可以修改 函数 对象,改变它的行为;
  • 在运行时,Python 可以修改 类 对象,改变它的行为;
  • 在运行时,Python 可以动态编译代码并加入到虚拟机中执行;

借助这些特性,我们可以实现程序运行时动态更新代码,也就是 代码热更新 !

对于一般程序而言,想要更新代码只有重启一条路。因此,拥有热更新能力的 Python 可以实现很不可思议的功能,具体如何进行呢?—— 我们从猴子补丁说起。

猴子补丁

猴子补丁 ( monkey patch )大家应该都听说过,这是一种在运行时添加、修改代码的技术,而无需修改源码。

json 序列化是一个很常见的操作,在 Python 可以这样进行:


  1. import json 
  2. json.dumps(some_data) 

ujson 是另一个 json 序列化实现,由纯 C 语言编写,效率比标准库中的 json 模块更高,用法一样:


  1. import ujson 
  2. ujson.dumps(some_data) 

那么,如果想把整个程序中的 json 操作都换成 ujson ,该怎么办呢?

直接引用 ujson 肯定是不行的,因为程序可能会引用第三方类库,我们肯定不想也不好改动第三方代码。以一个由 flask 框架实现的 api 为例,


  1. from flask import Flask, jsonify 
  2.  
  3. app = Flask(__name__) 
  4.  
  5. @app.route('/'
  6. def some_api(): 
  7.     return jsonify(some_data) 

jsonify 函数用于响应 json 数据,它调用标准库 json 模块对数据进行 json 序列化,可 flask 并不是我们开发的。

好在,利用 Python 执行过程的动态特性,我们可以在运行时替换 json 模块的相关函数实现。下面,我们编写 patch_json 函数,实现 dumps 和 loads 函数的替换:


  1. import json 
  2. import ujson 
  3.  
  4. def patch_json() 
  5.  json.dumps = ujson.dumps 
  6.     json.loads = ujson.loads 
  7.  
  8. patch_json() 

这样一来,只要 patch_json 函数成功执行,json 模块中的 dumps 、loads 函数就被换成了 ujson版本。后续就算从 json 模块导入,最终得到的也是 ujson 版本!

【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章