如何手动迭代IPython主循环?
我可以以某种方式实例化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)
在你的命令行中,只需进入文件所在的目录,然后执行:
ipython
run file.py
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)
这样做应该会让你的程序在解释器空闲时运行,同时仍然允许你像往常一样进行操作。