我找到了一种交互式处理curses 的方法,同时还能享受IPython 的大部分好处。它可以工作,但有一些限制,但没有我想要的那么好。
当然,最初的问题是我希望能够使用我的交互式 Python 会话,同时让它控制终端屏幕,使用 curses (ncurses) 模块(或urwid,例如)。一种解决方案是编写一个简单的 TCP 服务器,它带有一个简单的事件循环,该循环评估它从套接字读取的每个字符串,并发送回表示并返回结果的序列化字符串。如此处所述:SO:有没有一种方法可以交互式地对 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 会话中一样,它恰好正在更新另一个终端的屏幕并从中读取(通过诅咒输入函数)。
这种方法的问题和问题:
- 要退出似乎我必须从 IPython 控制台运行 quit() ,这不会以正常方式退出解释器。它似乎不允许
curses.wrapper()
重置终端,并且各种尝试调用.endwin()
,.resetty()
(当然在执行 a.savetty()
之后),.reset_shell_mode()
(and.reset_prog_mode()
) 等等都失败了。我已经尝试在调用之后在 main 中调用它们,curses.wrapper()
并且我已经尝试将它们注册为atexit
- 我如何干净地退出这样的会话?
- [Tab] 完成不起作用
- 如何让 IPython 的 [Tab] 通过 IPython 控制台会话完全工作到这些嵌入式内核之一?
- 调用 IPython
embed_kernel()
函数会将套接字信息打印到 curses 屏幕,此时该屏幕已经被初始化curses.wrapper()
。这很难看;另外,如果想做更有趣的工作,在curses中和调用embed_kernel()
函数之前,我看不到该函数打印到stdout或stderr的文本。- 如何
embed_kernel()
保持沉默并强制它通过其他机制注册连接详细信息?我可以给它我自己的套接字名称/使用路径吗?
- 如何
我相信我会想到其他问题,但我希望其他人会发现这个技巧很有用,并且会发现我想涉足 Python 诅咒编码时可以使用的其他技巧。