python热更新
- 热更新:不重启服务进程的情况下,对部分python逻辑替换(几秒内完成)
猴子补丁
monkey-patch: patching should be done as early as possible in the lifecycle of the program
直接替换函数:
# module.py
def module_func():
print('hello')
# hotfix.py
from . import module
def patched_func():
print("hello patched")
def hotfix_v1():
module.module_func = patched.func
局限性
有效场景:调用时,间接获取函数对象
# logic.py
from.import module
from.hotfix import hotfix_v1
module.module_func()h
otfix_v1()
module.module_func()
无效场景:代码中直接持有函数的引用,例如from … import …from … import …
cpyhon源码分析
Code objects are a low-level detail of the CPython implementation.Each one represents a chunk of executable code that hasn’t yetEach one represents a chunk of executable code that hasn’t yetbeen bound into a function.been bound into a function.
解决方案
替换PyFunctionObject.func_code
defhotfix_v2():
module.module_func.__code__ = patched_func.__code__
实际应用中还需要考虑:
- 更完善的支持:
- 除了code,还有defaults、doc等
- 递归遍历module、class中的所有function、method,支持property
- 变更识别
- 自动识别哪些module发生过变化
- 过滤site-packages中的模块
- 实例热更新hook
- Entity manager
- gc.get_objects()
以下开源库提供了类似的功能:以下开源库提供了类似的功能:
- pydevd / pydevd_reload.py
- ipython / autoreload.py