【发布时间】:2012-08-26 08:29:18
【问题描述】:
我找到了一种交互方式使用 curses 的方法,同时还能享受 IPython 的大部分好处。它可以工作,但有一些限制,但没有我想要的那么好。
当然,最初的问题是我希望能够使用我的交互式 Python 会话,同时使用 curses (ncurses) 模块(或 urwid,例如)控制终端屏幕.一种解决方案是编写一个简单的 TCP 服务器,它带有一个简单的事件循环,该循环评估它从套接字读取的每个字符串,并发送回表示并返回结果的序列化字符串。如此处所述:SO: Is there a way to interactively program a Python curses Application)。
这是一个更简单的技巧(假设您安装了 IPython)。
#!/usr/bin/python
#!/usr/bin/env python
from IPython import embed_kernel
import curses
def interact_with_curses(screen):
'''set global stdscr variable and run embedded IPython kernel
suitable to be called by curses.wrapper()
'''
global stdscr
stdscr = screen
embed_kernel()
if __name__ == '__main__':
curses.wrapper(interact_with_curses)
(为了让 SO 的语法突出显示高兴)。
运行这将导致输出大致如下:
[IPKernelApp] To connect another client to this kernel, use:
[IPKernelApp] --existing kernel-2869.json
然后切换到另一个可以运行的窗口或屏幕会话:
ipython console --existing kernel-2869.json
连接到该进程并使用它。
这已经足够好了。然后,您可以拨打stdscr.refresh() 之类的电话。使用您的 curses/window 和 pad 对象,在它们上调用 dir() 以探索它们的功能,并且通常使用代码就像您在正常的 IPython 会话中一样,它恰好正在更新不同终端的屏幕并从中读取它好吧(通过 curses 输入函数)。
这种方法的问题和问题:
- 要退出似乎我必须从 IPython 控制台运行 quit(),而这不会以正常方式退出解释器。似乎不允许
curses.wrapper()重置终端和各种尝试调用.endwin()、.resetty()(当然是在执行.savetty()之后)、.reset_shell_mode()(和.reset_prog_mode())等等都失败了。在调用curses.wrapper()之后,我尝试在main 中调用它们,并且我尝试使用atexit注册它们- 如何彻底退出此类会话?
- [Tab] 完成不起作用
- 如何让 IPython 的 [Tab] 通过与这些嵌入式内核之一的 IPython 控制台会话完全工作?
- 调用 IPython
embed_kernel()函数会将套接字信息打印到 curses 屏幕,此时已由curses.wrapper()初始化。这很难看;另外,如果想做更有趣的工作,在curses 中和调用embed_kernel()函数之前,我看不到该函数打印到stdout 或stderr 的文本。- 如何让
embed_kernel()静默并通过其他机制强制它注册连接详细信息?我可以给它我自己的套接字名称/路径吗?
- 如何让
我确定我会想到其他问题,但我希望其他人会发现这个技巧很有用,并且会发现一些其他技巧,当我想涉足 Python 诅咒编码时可以使用。
【问题讨论】: