Python与Cmd模块的扭曲集成

我喜欢Python的Twisted和Cmd。 我想一起使用它们。

我得到了一些工作,但到目前为止,我还没有想出如何使Tab-Completion工作,因为我没有看到如何在Twisted的LineReceiver中立即接收tab keypres事件(没有按Enter键)。

这是我的代码到目前为止:

#!/usr/bin/env python

from cmd import Cmd
from twisted.internet import reactor
from twisted.internet.stdio import StandardIO
from twisted.protocols.basic import LineReceiver

class CommandProcessor(Cmd):
    def do_EOF(self, line):
        return True

class LineProcessor(LineReceiver):
    from os import linesep as delimiter # makes newline work

    def __init__(self):
        self.processor = CommandProcessor()
        self.setRawMode()

    def connectionMade(self):
        self.transport.write('>>> ')

    def rawDataReceived(self, data):
        self.processor.onecmd(data)
        self.transport.write('>>> ')

StandardIO(LineProcessor())
reactor.run()

除了制表符完成之外,这有些作用。 我可以输入一个像“help”这样的命令,Cmd模块将打印结果。 但是我失去了Cmd模块的漂亮选项卡完整功能,因为Twisted每次缓冲一行。 我试图将LineProcessor.delimiter设置为空字符串,无济于事。 也许我需要找到其他一些Twisted来代替LineReceiver吗? 或者也许有一种更简单的方法可以避免我必须逐一处理每个角色?

我不能单独使用Cmd,因为我想将它作为一个网络应用程序,其中一些命令将导致发送数据,并且从网络接收数据将异步发生(并显示给用户)。

所以,无论我们从上面的代码开始还是完全不同的东西,我都想用Python构建一个友好的终端应用程序,以响应网络事件以及制表符完成。 我希望我可以使用已经存在的内容,而不必自己实施太多。


这种方法你遇到了一些困难:

  • Cmd.onecmd不会执行任何选项卡处理。
  • 即使这样做了,您的终端也需要处于Cbreak模式,以便将单个按键输入到Python解释器( tty.setcbreak可以解决这个问题)。
  • 正如你所知道的, Cmd.cmdloop并不知道反应堆,并会阻塞等待输入。
  • 然而,为了得到你想要的所有酷编辑,Cmd(实际上是readline)需要直接访问标准输入和标准输出。
  • 考虑到所有这些困难,您可能需要考虑让CommandProcessor在其自己的线程中运行。 例如:

    #!/usr/bin/env python
    
    from cmd import Cmd
    from twisted.internet import reactor
    
    class CommandProcessor(Cmd):
        def do_EOF(self, line):
            return True
    
        def do_YEP(self, line):
            reactor.callFromThread(on_main_thread, "YEP")
    
        def do_NOPE(self, line):
            reactor.callFromThread(on_main_thread, "NOPE")
    
    def on_main_thread(item):
        print "doing", item
    
    def heartbeat():
        print "heartbeat"
        reactor.callLater(1.0, heartbeat)
    
    reactor.callLater(1.0, heartbeat)
    reactor.callInThread(CommandProcessor().cmdloop)
    reactor.run()
    
    链接地址: http://www.djcxy.com/p/56495.html

    上一篇: Python Twisted integration with Cmd module

    下一篇: How do I unload (reload) a Python module?