可爱的 Python:动态重新装入
2008-11-13 13:20:12 来源:WEB开发网长期运行的动态进程
迄今为止,我们研究的工具已经通过在初始化时下载更新资源而获得了动态程序逻辑。这对于命令行处理或批处理很有意义,但对于长期运行的应用程序又会怎样。这种长期运行的应用程序最可能是一些不断响应客户机请求的服务器进程。但是在这个案例中,我们将使用为 以前的文章 开发的 curses_txt2html.py 来说明 Python 的 reload() 函数。程序 curses_txt2html 是 dmTxt2Html 本地副本的封装器。这里并不是第二次提到 curses 编程,谈一下 curses_txt2html 提供了一组交互式菜单以配置和运行多个连续的 Txt2Html 转换也足够了。
curses_txt2html 可以一直在后台运行,当切换到它的会话并运行转换时,我们希望它能够使用最新的程序逻辑。对于这个特定的简单示例,关闭和重新启动应用程序并不难,并不会带来特别的损害。但这很容易令人联想到其它一直运行着的进程(可能是说明会话中所执行操作状态的进程)。
在本文中,添加了新的 File/Update 子菜单。它被激活时只调用新的函数 update_txt2html() 。除了与提供发生的确认相关的 curses 调用之外,我们已经在本文的其它示例中看到过这些步骤:
'curses_txt2html.py' 动态更新函数
def
update_txt2html
():
# Check for updated functions (fail gracefully if not fetchable)
s = curses.newwin(6, 60, 4, 5)
s.box()
s.addstr(1, 2,
"* PRESS ANY KEY TO CONTINUE *" , curses.A_BOLD)
s.addstr(3,2,
"...downloading..." )
s.refresh()
try
:
from
urllib
import
urlopen
updates = urlopen(
'http://gnosis.cx/download/dmTxt2Html.py' ).read()
fh = open(
'dmTxt2Html.py' ,
'w' )
fh.write(updates)
fh.close()
s.addstr(3,2,
"Module [dmTxt2Html] downloaded to current directory" )
except
:
s.addstr(3,2,
"Download of updated [dmTxt2Html] module failed!" )
reload(dmTxt2Html)
s.addstr(4, 2,
"Module [dmTxt2Html] reloaded from current directory " )
s.refresh()
c = s.getch()
s.erase()
dyn_txthtml.py 和 update_txt2html() 函数之间有两个重要差异。其中一个差异是继续操作,并导入主 dmTxt2Html 模块而不只导入支持函数。这主要是简化了导入。这里的问题是我们使用 import dmTxt2Html 来访问模块,而不是 from dmTxt2Html import * 。从许多方面考虑,这是一个更安全的过程,但结果是使覆盖 dmTxt2Html 中的函数变得更困难(不论是无心地还是故意地)。如果我们要从 d2h_textfuncs 附加函数,则必须对导入的支持模块执行 dir() ,并将成员以属性形式附加到 "dmTxt2Html" 名称空间。执行这种样式的覆盖是留给读者的练习。
update_txt2html() 函数带来的最主要差异是 Python 的内置 reload() 函数的用法。只执行全新的 import dmTxt2Html 将 不 会覆盖以前导入的函数。请密切注意这一点!许多初学者认为重新导入模块将更新内存中的版本。这是错的。实际上,更新模块中函数的内存映像的方法是 reload() 模块。
以上示例中还执行了另一个小技巧。更新 dmTxt2Html 模块的下载位置是本地工作目录,而这个目录可能是(也可能不是)原来装入 dmTxt2Html 的目录。事实上,如果它在 Python 库目录中,那么您也许不在该目录中使用(也许对它没有用户许可权)。但 reload() 调用尝试先从当前目录装入,然后再尝试 Python 路径的其余部分。所以,不论下载是否成功, reload() 应该是一个安全的操作(虽然它可能装入新的模块,也可能不装入)。
更多精彩
赞助商链接