Python实时编码/调试

10

有没有一种方法可以在程序执行期间不暂停主程序,并且能够检查和修改程序变量,生成交互式Python控制台(最好是iPython)?类似于浏览器为JavaScript提供的功能。

我知道pdb.set_trace()IPython.embed(),但它们都会暂停程序执行,并需要将它们放置在程序源代码的某个位置。

这对于Python桌面游戏开发非常有用。


1
还想知道是否有这样的方法。顺便说一下,来自code包的code.InteractiveConsole(locals=locals()).interact()提供了类似于IPython.embed()的功能,但不需要安装IPython。 - starrify
除了必须生成控制台以更改变量的要求外,这听起来对我来说像是一个相当标准的调试器。 - rlms
1
@sweeneyrod 的确。如果不会对性能造成太大影响,我会使用 PyCharm 的免费版本。http://www.jetbrains.com/pycharm/ - David Pope
2个回答

4
你可以使用 threading 来自己编写多线程功能:
#!/usr/bin/python3

def _spawn_background_interpreter(*args,**kwargs):
    from threading import Thread
    def _open_interp(locs):
        import code
        code.interact(local=locs)
    locs = args[0] if args else None
    t = Thread(target=_open_interp, args=(locs,))
    t.setDaemon(True) #pre-3.3 API
    t.start()

使用_spawn_background_interpreter(locals())进行调用。

我没有测试过,但如果您的程序不会持续向控制台打印输出,则这可能是可行的 - 否则它将与交互式解释器混在一起。

“打开新控制台”的想法很有趣,但非常依赖于环境,因此我不会去处理。如果有更好的预打包解决方案,我会很感兴趣。

编辑:尝试使用multiprocessing解决方案:

def _spawn_background_interpreter(*args,**kwargs):
    from multiprocessing import Process
    import sys, os
    def _open_interp(locs,stdin):
        import code
        sys.stdin = os.fdopen(stdin)
        code.interact(local=locs)
    locs = args[0] if args else None
    fileno = sys.stdin.fileno()
    p = Process(target=_open_interp, args=(locs,fileno))
    p.daemon = True
    p.start()

我最初避免使用multiprocessing的原因是每个新进程都有自己的PID(和stdin)。因此,我必须将主线程的stdin传递给子进程,从那里开始变得有点复杂。请注意,在python 3.2及以下版本中存在一个错误,每次在multiprocessing进程中调用exit()时会导致回溯信息。这在3.3中已经修复。

不幸的是,multiprocessing代码只在符合POSIX标准的系统上运行,即不能在Windows上运行。虽然这是可以克服的,但需要更复杂的管道解决方案。

无论如何,如果你的主线程接近100%的CPU利用率,multiprocessing实现可能会为你提供更好的性能。如果你在*nix上,请尝试一下。


这很好,但是生成的控制台响应不太灵敏(运行非常缓慢),你有什么想法吗? - HankMoody
啊,你的主线程可能正在使用接近100%的CPU时间。在cPython中使用线程的标准警告适用。转换为多进程可能会有很大帮助。我现在离开电脑了,回来后会更新。 - roippi
@PythonFanboy 好的,我尝试了一下multiprocessing实现。虽然我不是100%满意它,但时间不够了,没法解决其中的问题。看看它是否更高效。 - roippi
@PythonFanboy,结果我不满意的原因是 Python 3.2 中的一个 bug。呵呵。 - roippi
不幸的是,我目前正在使用Windows,但是Python 3.3。如果没有其他选择,我将采用您的答案(线程),并尝试减少主线程的CPU使用率。 - HankMoody

1

我假设您熟悉在Eclipse下运行的PyDev。如果您准备中断主程序(这不是您想要的),它会提供出色的调试功能。然而,PyDev有一个名为“运行调试服务器”的功能,允许连接到现有的正在运行的程序。我自己没有尝试过,但建议您看一下,因为PyDev是Eclipse的一个优秀插件。 如果您尝试了它,我会对您的想法感兴趣。 请尝试查看:

http://pydev.org/manual_adv_remote_debugger.html

有关详细信息,请查看。祝你好运。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接