Python Twisted 与 Cmd 模块的集成

标签 python twisted stdin tab-completion python-cmd

我喜欢 Python 的 TwistedCmd .我想一起使用它们。

我得到了一些工作,但到目前为止我还没有想出如何使制表符完成工作,因为我没有看到如何在 Twisted 的 LineReceiver 中立即接收制表键事件(不按 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 构建一个漂亮、友好的终端应用程序,它可以响应网络事件以及 Tab 键完成。我希望我可以使用现有的东西,而不必自己实现太多。

最佳答案

这种方法有几个困难:

  • Cmd.onecmd 不会进行任何制表符处理。
  • 即使是这样,您的终端也需要处于 cbreak 模式,以便单个击键能够进入 Python 解释器(tty.setcbreak 可以解决这个问题)。
  • 如您所知,Cmd.cmdloop 不是 react 堆感知的,会阻塞等待输入。
  • 然而,要获得您想要的所有很酷的行编辑,Cmd(实际上是 readline)需要直接访问 stdin 和 stdout。

鉴于所有这些困难,您可能希望考虑让 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()

关于Python Twisted 与 Cmd 模块的集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8568241/

相关文章:

python - keras 的 Model.train_on_batch 和 tensorflow 的 Session.run([train_optimizer]) 有什么区别?

python - 将方法从文件导入到类中

python - 写入 UDP 套接字是否会阻塞?

c - 检查何时没有任何内容通过管道传输到标准输入

c - 读取未知数量的整数并用文字打印

python - 函数默认仅返回第一个输出值

python - Python 赋值后类对象的继承

python - 对列表列表中的元素求和

python - 使用 MSN 协议(protocol)运行 twins.words 示例时出现异常

R使用system()将数据帧传递到另一个程序