相信很多使用python者都对reload方法比较熟悉了,通过不间断地reload可以实现某一module的热更新,主要就能在不重启应用的情况下实现部分模块的更新。但这种方法仅限于reload当前工作目录下的module,对于通过setuptools安装的egg包就不灵了,具体分析如下:
(1)python 的import或者reload都是根据sys.path来进行查找相关module的,找到第一个匹配的module之后就进行加载然后退出此操作
(2)sys.path是有一定的顺序的
(3)通过setuptools 的easy_install进行安装的package,每个版本都保留在site-packages中
(4)sys.path正常情况下只有在python进程启动的时候进行赋值
(5)通过easy_install进行安装后easy_install.pth中记录的已经是最新版的package,但如果此时没有重启python进程,则sys.path中记录的还是原有的package位置,这时reload的话首先找到的还是老版本的package,也就是说新版并未生效
怎么解决这一问题?怎么在不重启程序的情况下使用新版的package?
通过研究python代码可以知道,python在启动的时候会加载 site.py,site.py中有一个main()函数负责对sys.path进行赋值操作,为实现我们在不重启程序就能使用最新版package的目的,可以通过显式调用site.py中的main()函数来操作,具体代码如下:

# -*- coding: utf-8 -*-

import sys
import site
import time
import os.path
import copy def reload_module(module_str):
'''
reload module
'''
paths_old = copy.deepcopy(sys.path)
# invoke site.main to get updated sys.path
site.main()
paths_new = copy.deepcopy(sys.path)
updated = []
# parse updated packages
for item in paths_new[len(paths_old):]:
_, egg_name = os.path.split(item)
# egg_name like this : requests-1.1.0-py2.7.egg
# parse real package name
if len(egg_name) > 0:
package_name = egg_name.split('-')[0]
updated.append(package_name)
# erase old version packages
sys.path = []
for item in paths_new[:len(paths_old)]:
_, egg_name = os.path.split(item)
if len(egg_name) > 0:
package_name = egg_name.split('-')[0]
if package_name in updated:
# a new version is already exists, so erase the old one
pass
else:
sys.path.append(item)
# append the updated
sys.path.extend(updated)
if sys.modules.has_key(module_str):
print 'need reload'
reload(sys.modules[module_str])
else:
print 'need import'
try:
exec 'import %s' %module_str
except Exception, e:
print e def main():
import requests
while True:
time.sleep(2)
reload_module('requests')
print requests.__version__ if __name__ == '__main__':
main()

如果在程序运行过程中安装了新版的requests,则程序运行结果如下所示:
C:\Users\JerryKwan\Desktop>python get_current_version.py
need reload
1.2.0
need reload
1.2.0
need reload
1.2.0
need reload
1.2.0
need reload
1.2.3
need reload
1.2.3
need reload
1.2.3

不重启程序使用最新版package的更多相关文章

  1. linux下通过脚本实现自动重启程序的方法

    无论什么程序都不可能完美无缺,理论上,任何程序都有 Core Dump 的一天,正式运营的程序,尤其是服务器程序,一旦 Core Dump ,后果不堪设想,有过服务器开发经验的朋友,一定都经历过深夜美 ...

  2. 黄聪:C#使用Application.Restart重启程序出错解决办法

    调用 Application.Restart重启程序出错 解决办法,就是给程序的.exe文件,加上下面的设置

  3. C# 程序修改config文件后,不重启程序刷新配置ConfigurationManager

    基本共识: ConfigurationManager 自带缓存,且不支持 写入. 如果 通过 文本写入方式 修改 配置文件,程序 无法刷新加载 最新配置. PS. Web.config 除外:Web. ...

  4. golang 通过fsnotify监控文件,并通过文件变化重启程序

    一.下载我们需要的包 > go get github.com/fsnotify/fsnotify 二.使用fsnotify监控文件 package main; import ( "gi ...

  5. 零停重启程序工具Huptime研究

    目录 目录 1 1. 官网 1 2. 功能 1 3. 环境要求 2 4. 实现原理 2 5. SIGHUP信号处理 3 6. 重启线程 4 7. 重启目标程序 5 8. 系统调用钩子辅助 6 9. 被 ...

  6. 【转】Android 中处理崩溃异常并重启程序出现页面重叠的问题

    原文地址:http://blog.csdn.net/jiang547860818/article/details/53641113 android开发中经常会遇到程序异常,而已常常会遇到一出现异常AP ...

  7. nw.js node-webkit基本程序结构与配置package.json配置说明

    (一)基本程序结构 如上图,是一个nw程序的基本组织结构,在根目录下有package.json(程序的配置文件)和index.html(可以是任意名称,应用的启动页面):js/css/resource ...

  8. Winform读写App.config文件以及重启程序

    //重启主程序 //System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Locatio ...

  9. 微信小程序基于最新版1.0开发者工具分享-小试牛刀(视频)+发布流程

    第一章:小程序初级入门教程 小试牛刀[含视频] 视频地址:https://v.qq.com/x/page/i0554akzobq.html 这一章节中,我们尝试着写一个最简单的例子,包含 2 个静态页 ...

随机推荐

  1. NetworkComms V3 之发送UDP广播消息

    NetworkComms网络通信框架序言 NetworkComms通信框架,是一款来自英国的c#语言编写的通信框架,历时6年研发,成熟稳定,性能可靠. NetworkComms v3目前只支持基本的U ...

  2. 关于MediaPlayer的详细介绍

    1)如何获得MediaPlayer实例:可以使用直接new的方式:MediaPlayer mp = new MediaPlayer();也可以使用create的方式,如:MediaPlayer mp ...

  3. C# 文件夹加密

    可以加密文件内容,也可以对文件夹本身进行加密,本文对文件夹加密. 一.指定或生成一个密钥 1)指定的密钥 /// <summary> /// 密钥,这个密码可以随便指定 /// </ ...

  4. Phonebook 导出联系人到SD卡(.vcf)

    2014-01-13 16:53:55 1. 在Phonebook中导出联系人到内部存储,SD卡或者通过蓝牙.彩信.邮件等分享联系人时,通常会先将选择的联系人打包生成.vcf文件,然后将.vcf文件分 ...

  5. 正则表达式 java

    如果你曾经用过Perl或任何其他内建正则表达式支持的语言,你一定知道用正则表达式处理文本和匹配模式是多么简单.如果你不熟悉这个术语,那么"正则表达式"(Regular Expres ...

  6. Python的平凡之路(6)

    一.面向对象编程介绍 1 编程范式:          编程范式(Programming Paradigm)是某种编程语言典型的编程风格或者说是编程方式.随着编程方法学和软件工程研究的深入,特别是OO ...

  7. 关于async

    以前做项目很少理会async这个属性 今天做项目的时候 由于原来是点击查看按钮进行查看 现在要把需求改成默认进入页面就直接显示内容 我在js加载的时候就需要调用一次查看的点击事件 我在整个js初始加载 ...

  8. 2-legged oauth & 3-legged oauth

    3-legged oauth resource owner, client, server. resource owner 给client访问权限去访问resource owner在server上的r ...

  9. Boundaries

    Using Third-Party Code There is a natural tension between the provider of an interface and the user ...

  10. Git工作流指南:Pull Request工作流

    参考地址:http://blog.jobbole.com/76854/ Pull Requests是Bitbucket上方便开发者之间协作的功能.提供了一个用户友好的Web界面,在集成提交的变更到正式 ...