如何手动迭代IPython主循环?

5 投票
2 回答
2515 浏览
提问于 2025-04-16 23:21

我可以以某种方式实例化ipython(或者更好的是,ipython-qtconsole),并手动逐步执行它的主循环吗?

我想实时编辑panda3d程序。

编辑1:
这里有一段代码示例,可以稍微说明一下我想做的事情。

import sys

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        self.qtApp = QApplication(sys.argv)
        label = QLabel("Hello World")
        label.show()
        self.m = loader.loadModel("frowney")
        self.m.reparentTo(render)

        while 1:
            self.qtApp.processEvents()  #manual step trough Qt loop
            taskMgr.step()              #manual step trough Panda3D loop

app = MyApp()

你可以看到我如何手动逐步执行panda和qt,我想用ipython做同样的事情,如果可能的话。

回答
完整文件:

from direct.showbase.ShowBase import ShowBase
from IPython.lib import inputhook
class MyApp(ShowBase):

def __init__(self):
    ShowBase.__init__(self)
    self.m = loader.loadModel("frowney")
    self.m.reparentTo(render)

def stepMe(self):
    taskMgr.step()              #manual step trough Panda3D loop
    return 0  
if __name__ == "__main__":  
    app = MyApp()  
    inputhook.set_inputhook(app.stepMe)

在你的命令行中,只需进入文件所在的目录,然后执行:

  1. ipython
  2. run file.py
  3. app.m.setPos(1,1,1)

2 个回答

1

在ipython调试器中运行这个脚本,可以使用下面的命令:

%run -d -b40 myscript

这里的 -b40 参数是用来设置一个断点的,断点是在脚本的第40行(这应该是你想要调试的循环的第一行)。在提示符下输入 c 可以开始运行脚本,程序会在断点处停下来。输入 h 可以获取调试器的帮助信息。

2

你说的“实时编辑panda3d程序”,是指在运行程序的时候修改一些东西来测试吗?还是说在交互环境中对程序的结构进行持久性的修改呢?

在交互式的Python会话中,跳过你的循环其实很简单。你可以把 while 1: 替换成一个方法声明,比如 def step(self):,然后每次调用这个方法来执行一步。

import sys

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        self.qtApp = QApplication(sys.argv)
        label = QLabel("Hello World")
        label.show()
        self.m = loader.loadModel("frowney")
        self.m.reparentTo(render)

    def step(self):
        self.qtApp.processEvents()  #manual step trough Qt loop
        taskMgr.step()              #manual step trough Panda3D loop
        return 0                    #PyOS_InputHook expects an integer

if __name__ == "__main__":
    app = MyApp()
    while 1: app.step()

使用 if __name__ == "__main__" 来作为主循环时,你的文件在独立运行时依然能正常工作。不过现在你可以把它导入到一个交互会话中,并在每一步之间修改内容。

>>> import myfile
>>> app = myfile.MyApp()
>>> app.step()
>>> app.something = something_else
>>> app.step()

要把它添加到IPython的事件循环中,这样在使用解释器时它就会运行,你可以使用 IPython.lib.inputhook.set_inputhook()(在IPython 0.11中新增的功能)。

>>> from IPython.lib import inputhook
>>> inputhook.set_inputhook(app.step)

这样做应该会让你的程序在解释器空闲时运行,同时仍然允许你像往常一样进行操作。

撰写回答