在Python中无需重启主脚本加载/重载部分代码

6 投票
4 回答
4794 浏览
提问于 2025-04-17 05:05

简介

我最近在玩Twisted,刚学Python不到一个月。我最开始的想法是玩一些我熟悉的东西,比如IRC(互联网聊天)。多亏了ircLogBot.py这个例子,我已经成功建立了一个基本的IRC连接。

问题

我想要一些代码可以在每次收到IRC事件(比如私信、CTCP、加入或离开频道)时运行。为了方便调试,我希望能在不关闭整个脚本和重新连接IRC服务器的情况下,修改这段代码并重新加载它。

最后的说明

这个解决方案不一定要用Twisted,因为我对它还不是很了解。不过我猜,作为一个事件驱动的框架,Twisted应该能很好地处理这种情况。

4 个回答

2

你可以看看 'livecoding',这个工具可以处理代码的重新加载,可能会符合你的需求。不过要注意,'livecoding' 对代码文件(文件夹)有自己的要求,这些要求不一定符合 Python 的标准。

另外一个选择是自己动手做一个系统,使用 reload,就像 Raymond 提到的那样。如果你的代码和状态数据分开得很好,可能会很容易实现。

9

Twisted里有一个内置的功能,叫做 twisted.python.rebuild,它比Python自带的 reload 函数更强大。虽然它也有一些限制,但它最大的不同之处在于,它能找到旧的对象实例,并把它们的类替换成新版本的类。(主要的限制是,如果你修改了 __init__ 方法,你需要注意你的实例可能会有旧的状态,这些状态和你当前的版本不匹配,这就是 rebuild.Sensitive 的作用。)

如果你想让事情变得更炫、更自动化,你可以设置一个文件系统监控器,来检测文件的变化,并在文件变化时用 rebuild 重新加载相关的模块。在Linux上,你可以使用Twisted的 inotify 来接收变化通知,而在OS X上,你可以使用 cfreactorFSEvents API,通过 PyObjC 来实现。(我不太清楚在win32上有哪些文件修改监控方案,但那里也可能有类似的功能。)

3

设置一个定期的事件(每隔几秒)来重新加载你正在调试的模块。可以使用内置的 reload() 函数来实现这个功能。

你可能想把它放在一个try/except块里,这样如果你在调试的模块中引入了错误,它也能处理这个情况。这样可以让服务器在出现错误时仍然保持运行 :-)

撰写回答