【问题标题】:Working with curses in IPython. How can I improve this?在 IPython 中使用 curses。我该如何改进呢?
【发布时间】: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 诅咒编码时可以使用。

【问题讨论】:

    标签: python ipython ncurses


    【解决方案1】:

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

    从一个终端只需输入:

    ipython kernel
    

    这将打印一行类似的内容:

    [IPKernelApp] To connect another client to this kernel, use:
    [IPKernelApp] --existing kernel-14321.json
    

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

    ipython console --existing kernel-14321.json
    

    ...您将进入一个看似完全正常的 IPython 会话。唯一的区别是您实际上是在另一个窗口中访问“远程”IPython 内核会话。从那里您将能够使用 curses 函数、查看其他窗口中的更改、对其输入输入、使用 [Tab]-completion 等等。

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

    但是,总的来说,这个模型比我去年在我的问题中描述的更干净、更容易。我不知道是 IPython (0.13.1) 的较新版本还是简单的无知让我之前的尝试有些笨拙。

    【讨论】:

    • 嗨,Jim,我是 IPython 的开发人员之一 - 这是玩 ncurses/urwid 的一种很酷的方式,感谢分享! ipython kernel 入口点在 0.12 中可用。这个技巧也适用于ipython notebookipython qtconsole 入口点!
    【解决方案2】:

    我找到了tab补全的答案,你可以使用get_ipython()获取IPython shell对象,然后调用init_completer()就可以了:

    get_ipython().init_completer()
    

    应该可以获取内核并关闭它,退出终端应用程序。但是在文档中爬行到目前为止还没有发现如何。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-15
      • 1970-01-01
      • 2021-04-18
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多