在调试器中更改Python代码
有没有什么调试工具可以在调试时修改Python代码的?
换句话说,就是当程序运行时出现错误,调试工具暂停,我可以随意修改代码,然后告诉程序继续运行。
我知道这样做会有一些问题,比如如果我在运行时重新定义了一个函数,之前的地方仍然会指向旧的定义等等。我对此没问题,因为我只是想在简单的情况下做一些小修正。
另一方面,我也想知道理论上是否有可能在不遇到这些问题的情况下修改Python代码:也就是说,能否以某种方式更新所有指向被修改对象的引用等等。我几乎可以肯定第二个问题的答案是否定的,但如果我错了,我想知道。
补充:如果我的目标(在出现异常时交互式地修改代码,然后继续执行)可以在不使用调试工具的情况下实现,那也很好。我不一定需要用调试工具。
5 个回答
你可以使用 xreload 来更新正在运行的 Python 程序中的代码:
http://svn.python.org/projects/sandbox/trunk/xreload/xreload.py
不过,这个方法有很多限制,具体的限制在文件的开头有说明。我不太确定这是否能解决你想要的问题——你是想真正阻止异常继续传播吗?这可不仅仅是更新正在运行的程序那么简单。
是的,pdb可以做到这一点。不过,你需要在其他编辑器里进行修改,直到你重启程序,这些修改才会生效。
但因为你只是想做一些小改动,这其实不是个大问题。不过,你不能直接修改正在运行的代码(除了用reload,下面会提到),因为修改代码会导致代码和程序的状态不同步。
使用调试器,你可以测试你想要的改动。你可以把想要修改的代码粘贴进去,这样就能测试它是否正确,而不需要重新运行整个程序。但在这种情况下,你并不是在编辑文件。
(在某些特定情况下,通过小心使用“reload()”,你可能不需要重启,但这样做可能不太值得。)
因为你可以随时随意地修改普通类的内容,所以不需要更新对象的引用:你只需要用新的方法和其他属性更新类的 __dict__
就可以了。
问题出在函数的引用上:你不能在不改变函数身份的情况下更新一个函数。你可以使用代理函数,这些代理函数总是通过名称查找真实的函数,而你可以随时更改真实的函数。或者,你可以设计你的代码,让它不长时间保存函数的引用;一旦函数被更新,之后会很快通过名称查找,但之前传递的旧引用会继续执行一段时间。
这种修补在长时间运行的系统中是有意义的,当你想要在不严重停机的情况下升级它时:你可以暂停一下,升级几个类和函数,然后再继续运行。根据我所知道的,Erlang 也以类似的方式进行实时更新。