在IPython中使用curses.我怎样才能改善这个?

Jim*_*nis 6 python ncurses ipython

我已经找到了一种与诅咒交互式工作的方法,同时仍然享受着IPython的大部分好处.它的作用有一定的局限性,但并不像我想的那么好.

当然,最初的问题是,我希望能够使用curses(ncurses)模块(例如urwid)控制终端屏幕,同时使用我的交互式Python会话.一种解决方案是编写一个简单的TCP服务器,其中包含一个简单的事件循环,用于评估从套接字读取的每个字符串,并发回代表并返回结果的序列化字符串.如下所述:SO:有没有办法交互式编程Python curses应用程序).

这是一个稍微简单的技巧(假设你安装了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)
Run Code Online (Sandbox Code Playgroud)

(稍微勉强让SO的语法突出显示开心).

运行此将导致输出大致如下:

 [IPKernelApp] To connect another client to this kernel, use:
            [IPKernelApp] --existing kernel-2869.json
Run Code Online (Sandbox Code Playgroud)

并切换到另一个窗口或屏幕会话,您可以运行:

ipython console --existing kernel-2869.json
Run Code Online (Sandbox Code Playgroud)

连接到该流程并使用它.

这很好.然后你可以调用类似的东西stdscr.refresh().使用你的curses/window和pad对象,调用dir()它们来探索它们的功能,并且通常使用代码,就像你在正常的IPython会话中一样,恰好正在更新不同终端的屏幕并从中读取(通过curses输入函数).

这种方法的问题和问题:

  • 要退出它似乎我必须从IPython控制台运行quit(),并且这不会以正常方式退出解释器.它似乎并没有让curses.wrapper()终端和各种尝试重置叫.endwin(),.resetty()(已经执行了之后.savetty()当然), .reset_shell_mode()(和.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 curses编码时,我会发现其他一些技巧.

Jim*_*nis 8

事实证明,我们现在可以以相当自然的方式使用IPython来交互式地使用curses.

从一个终端输入:

ipython kernel
Run Code Online (Sandbox Code Playgroud)

这将打印一行如下:

[IPKernelApp] To connect another client to this kernel, use:
[IPKernelApp] --existing kernel-14321.json
Run Code Online (Sandbox Code Playgroud)

从另一个终端/窗口类型:

ipython console --existing kernel-14321.json
Run Code Online (Sandbox Code Playgroud)

...而且你将处于看似完全正常的IPython会话中.唯一的区别是你实际上是在另一个窗口中访问"远程"IPython内核会话.从那里你可以使用curses函数,查看其他窗口中的更改,输入其中的输入,使用[Tab] -completion等等.

请注意,[Ctrl] - [D]将提供退出IPython 控制台(客户端),同时quit()关闭IPython 内核(远程窗口---服务器).

但是,总的来说,这个模型比我去年在我的问题中描述的更清晰,更容易.我不知道它是不是更新版本的IPython(0.13.1),还是简单的无知让我以前的尝试有点笨拙.

  • 嗨吉姆,我是IPython的开发者之一 - 这是一个很酷的方式来玩ncurses/urwid,感谢分享!`ipython kernel`入口点在0.12中可用.这个技巧也适用于`ipython notebook`和`ipython qtconsole`入口点! (2认同)

小智 2

我找到了制表符补全的答案,您可以使用 获取 IPython shell 对象get_ipython(),然后调用init_completer()它:

get_ipython().init_completer()
Run Code Online (Sandbox Code Playgroud)

应该也可以获取内核并将其关闭,以退出终端应用程序。但到目前为止,爬行文档尚未发现如何操作。