奇门武功:如何实现代码热更新

本文转载自微信公众号「小菜学编程」,作者fasionchan。转载本文请联系小菜学编程公众号。

创新互联服务项目包括临沂网站建设、临沂网站制作、临沂网页制作以及临沂网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,临沂网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到临沂省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

经过 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. app = Flask(__name__)
  3. @app.route('/')
  4. def some_api():
  5.     return jsonify(some_data)

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

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

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

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

需要特别注意,json 模块属性在 patch_json 调用前就被直接引入,将不受 patch_json 控制:

 
 
 
 
  1. import json
  2. from json import dumps
  3. patch_json()
  4. # 执行 json 模块原来的版本,而不是 ujson 版本
  5. dumps(some_data)
  6. # 执行 ujson 版本
  7. json.dumps(some_data)

因此,许多应用猴子补丁的程序,在开头处便要执行替换逻辑,确保类似的现象不会发生。

猴子补丁的应用范围很广,一般用来特换类库实现或者在单元测试中进行 mock 。诸如greenlet 采用猴子补丁将阻塞的库函数替换成非阻塞的版本:

 
 
 
 
  1. import gevent.monkey
  2. gevent.monkey.patch_all()

由于猴子补丁可能会影响代码的可读性,应用不当可能导致一些奇怪的问题,因此不能滥用。

实际上,除了猴子补丁,Python 还提供了 reload 函数,用于重新加载模块。那么,我们应该如何使用 reload 函数呢?它有哪些局限性吗?

网站名称:奇门武功:如何实现代码热更新
URL标题:http://www.hantingmc.com/qtweb/news4/105654.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联